Unity3d中charactor unity fpscontrollerr正确的播放攻击

navigation - Unity3D OffNavMesh jump issue - Stack Overflow
Join the Stack Overflow Community
Stack Overflow is a community of 7.1 million programmers, just like you, helping each other.
J it only takes a minute:
I have set up Unity navigation meshes (four planes), navigation agent (sphere) and set up automatic and manual off mesh links. It should now jump between meshes. It does jump between meshes, but it does that in straight lines.
In other words, when agent comes to an edge, instead of actually jumping up (like off mesh link is drawn) it just moves straight in line but a bit faster. I tried moving one plane higher than others, but sphere still was jumping in straight line.
Is it supposed to be like this? Is it possible to set up navigation to jump by some curve? Or should I try to implement that myself?
3,708133181
Its recommended to solve your problems via animation. Just create a Jump animation for your object, and play it at the correct time.
The position is relative, so if you increase the Y-position in your animation it will look like the object is jumping.
This is also how the Unity sample is working, with the soldiers running around.
I came by this question, and had to dig through the Unity sample. I just hope to make it easier for people by extracting the important bits.
To apply your own animation/transition across a navmesh link, you need to tell Unity that you will handle all offmesh link traversal, then add code that regularly checks to see if the agent is on an offmesh link. Finally, when the transition is complete, you need to tell Unity you've moved the agent, and resume normal navmesh behaviour.
The way you handle link logic is up to you. You can just go in a straight line, have a spinning wormhole, whatever. For jump, unity traverses the link using animation progress as the lerp argument, this works pretty nicely. (if you're doing looping or more complex animations, this doesn't work so well)
The important unity bits are:
_navAgent.autoTraverseOffMeshLink = //in Start()
_navAgent.currentOffMeshLinkD //the link data - this contains start and end points, etc
_pleteOffMeshLink(); //Tell unity we have traversed the link (do this when you've moved the transform to the end point)
_navAgent.Resume(); //Resume normal navmesh behaviour
Now a simple jump sample...
using UnityE
[RequireComponent(typeof(NavMeshAgent))]
public class NavMeshAnimator : MonoBehaviour
private NavMeshAgent _navA
private bool _traversingL
private OffMeshLinkData _currL
void Start()
// Cache the nav agent and tell unity we will handle link traversal
_navAgent = GetComponent&NavMeshAgent&();
_navAgent.autoTraverseOffMeshLink =
void Update()
//don't do anything if the navagent is disabled
if (!_navAgent.enabled)
if (_navAgent.isOnOffMeshLink)
if (!_traversingLink)
//This is done only once. The animation's progress will determine link traversal.
animation.CrossFade("Jump", 0.1f, PlayMode.StopAll);
//cache current link
_currLink = _navAgent.currentOffMeshLinkD
//start traversing
_traversingLink =
//lerp from link start to link end in time to animation
var tlerp = animation["Jump"].normalizedT
//straight line from startlink to endlink
var newPos = Vector3.Lerp(_currLink.startPos, _currLink.endPos, tlerp);
//add the 'hop'
newPos.y += 2f * Mathf.Sin(Mathf.PI * tlerp);
//Update transform position
transform.position = newP
// when the animation is stopped, we've reached the other side. Don't use looping animations with this control setup
if (!animation.isPlaying)
//make sure the player is right on the end link
transform.position = _currLink.endP
//internal logic reset
_traversingLink =
//Tell unity we have traversed the link
_pleteOffMeshLink();
//Resume normal navmesh behaviour
_navAgent.Resume();
//...update walk/idle animations appropriately ...etc
Not sure what version of unity you are using but you could also try this, I know it works just fine in 4:
string linkType = GetComponent&NavMeshAgent&().currentOffMeshLinkData.linkType.ToString();
if(linkType == "LinkTypeJumpAcross"){
Debug.Log ("Yeah im )");
also just some extra bumf for you, its best to use a proxy and follow the a navAgent game object:
Something like:
AIMan = this.transform.
AI_Proxy.transform.position = AIM
And also be sure to use:
AI_Proxy.animation["ProxyJump"].blendMode = AnimationBlendMode.A
If you are using the in built unity animation!
K, that's my good deed for this week.
Your Answer
Sign up or
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Post as a guest
By posting your answer, you agree to the
Not the answer you're looking for?
Browse other questions tagged
The week's top questions and answers
Important community announcements
Questions that need answers
By subscribing, you agree to the
rev .25989
Stack Overflow works best with JavaScript enabledunity CharactorController下Move()官方示例下跳跃时主角无法移动操作问题。
时间: 16:22:16
&&&& 阅读:87
&&&& 评论:
&&&& 收藏:0
标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&
public float speed = 6.0F;
public float jumpSpeed = 8.0F;
public float gravity = 20.0F;
moveDirection = ;
void Update() {
controller = GetComponent&CharacterController&();
if (controller.isGrounded) {
moveDirection = new (("Horizontal"), 0, ("Vertical"));
moveDirection = transform.TransformDirection(moveDirection);
moveDirection *=
if (("Jump"))
moveDirection.y = jumpS
moveDirection.y -= gravity * ;
controller.Move(moveDirection * );
上面是官方给出的例子,由于检测移动是只能在地面上才能用,所以要将检测移动的代码移出至判定外。 但是将判定位移移出后Y轴将会一直为0,所以需要定义一个变量用来计算当前Y轴方向速度。
修改后代码:
public float speed = 6.0F;
public float jumpSpeed = 8.0F;
public float gravity = 20.0F;   public float verVel
//vertical velocity
moveDirection = ;
void Update() {
controller = GetComponent&CharacterController&();&     moveDirection = new (("Horizontal"), 0, ("Vertical"));    
moveDirection = transform.TransformDirection(moveDirection);
moveDirection *=
if (controller.isGrounded) {
  if (("Jump"))
moveDirection.y = jumpS
verVel = -= gravity * Time.deltaT
moveDirection.y = verV
controller.Move(moveDirection * );
原创:标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&原文:/m-f-s/p/6106616.html
教程昨日排行
&&国之画&&&& &&&&&&
&& &&&&&&&&&&&&&&
鲁ICP备号-4
打开技术之扣,分享程序人生!转自:/alongu3d/archive//3111736.html
这篇教材是来自教程团队成员&,&他是的开发支持团队的工程师。欢迎来到Unity3D for iOS系列教程的第二部分!在这个系列的中,你已经学习了Unity的一些基本技能来构建一个非常简单的项目,并把它部署到iOS设备上。在继续这篇教程之前,你要确认已阅读过第一部分。现在进入第二部分,你要添加一些功能来增强我们的项目,这些功能包括更好的角色移动,和更好的游戏背景。你也会学习如何使用Unity Remote来调试。游戏再次开启!
让我们开始:改变背景
打开你在教程第一部分的Unity项目。如果你还没有准备好,这里是下载的链接:&, .在教程的这个部分,你要在一个新的场景里做修改,所以你可以容易的打开老的那个来参考,如果你喜欢。选择FileSave Scene as&,并命名你的新场景为Level_2. 这个新的Level_2场景会添加到项目视图中。所有你在前一个场景中用到的资源,例如,脚本,在你新的场景中都可以使用。你可以改变Level_2场景中的GameObject,而不影响Level_1中同样的物件。
好好地享受吧
首先你要增强角色的机动性。目前你那个英勇的小方块只是会向前和向右旋转。那种移动不是非常平滑和有趣的。Character Controller是一个你可以连接到GameObject的Unity组件,它帮助你创建更加逼真的运动。你可以通过脚本函数来控制Character Controller.举例来说,你可以调用一个预先定义的SimpleMove函数来移动角色。这个SimpleMove函数用一个Vector3作为输入,来表示作用于移动的速度。角色的移动会根据重力自动计算,这样允许它爬坡和上下楼梯。角色也会绕过任何障碍物,它会找出它的路径,而不需要你写代码来关注这点。来
看看这究竟是啥意思,在Hierarchy视图中选择这个方块GameObject(你的角色),然后选择
&ComponentPhysicsCharacter Controller.&你会看见一个对话框让你确认是否用Character
Controller来替代Box Collider点击&Replace&在Inspector中你会看到一个针对Charactor COntroller的新组件。你将要创建一个全新的脚本来控制玩家的移动,所以你不再需要在这个场景中绑定MoveSimple脚本到你英勇的小方块上。在Inspector中,点击MoveSimple脚本右上角的齿轮图标,然后选择删除组件。这个脚本就不会在Inspector中出现了。选择AssetsCreateJavaScript创建一个新的Javacript资源,然后命名它为MoveAround. 双击这个新的脚本,在MonoDevelop中打开它。删除自动生成的函数,然后添加下面的代码:
var speed : float = 3.0;
var rotateSpeed : float = 3.0;
function Update () {
var controller : CharacterController = GetComponent(CharacterController);
// Rotate around y - axis
transform.Rotate(0, Input.GetAxis ("Horizontal") * rotateSpeed, 0);
// Move forward / backward
var forward : Vector3 = transform.TransformDirection(Vector3.forward);
var curSpeed : float = speed * Input.GetAxis ("Vertical");
controller.SimpleMove(forward * curSpeed);
@script RequireComponent(CharacterController)
保存你的修改。在这个脚本中的最后一行指定这个脚本只能连接到有Character Controller组件的的GameObject上。这个Update()函数获取一个Character Controller组件的句柄。根据代表左右移动的输入,让它围绕y轴做旋转变换。缺省情况下,左右移动由左右箭头和A/D键来控制的。Input.GetAxis()的值范围是-1到+1. 围绕着y轴,负值会产生一个逆时针旋转,正值产生一个顺时针的旋转。SimpleMove
函数根据从Input.GetAxis(&Vertical&)获取的输入让角色来朝前或朝后移动。这个输入由前后箭头或W/S键来触发。与水平输入一
样,the Input.GetAxis()的值范围从-1到+1,负值和正值分别代表向后和向前移动。你使用一个速度因子来控制旋转角度和移动的距离。关联新的脚本到英勇的小方块上。现在你知道该如何做了。(提示:如果你不记得了,这是ComponentsScriptsMove Around.:])当你完成后,在角色的Inspector中,你应该看到一个新的Move Around脚本组件。为啥不用the Unity Editor试试旋转你的英勇的小方块呢?点击Play按钮,然后体验你新创建的移动效果 & 哦,体验一下可以左右旋转,前后移动的快乐。使用left/right/up/down按键四处转转,然后也测试一下W/A/S/D键。玩家现在移动的更加顺畅了,感谢the Character Controller组件和你编写脚本的基因。继续之前,拍拍背休息一下吧. :]
用Unity Remote调试
在上个教程中,你也许注意到,在你的iOS设备上测试你的项目有一点麻烦。导出到Xcode项目,构建和在你的设备上运行的整个过程要花费一些时间,这些时间实际的增加到了开发过程中。好的消息是,这里有一个更好的方式!最快的方式来在iOS上调试你的游戏是使用一个叫做 Unity Remote的应用。这让你跳过为你的iOS构建项目,启动xcode然后部署在你的设备上的这些步骤,使用Unity Remote iOS应用,你可以链接你的iOS到Unity Editor,然后从iOS设备来控制你的Unity Editor。这点可以让你快速的在Unity Editor中调试你的游戏。
Unity Remote可以通过 免费获取到。下载,然后安装这个应用在你的设备上。
注意:要使用UnityRemote,需要你的iOS设备和你的电脑应该在同一个Wi-Fi网络中。另外,要让这种方式能够运作,Unity
Editor窗口必须在前台。如果你吧Unity Editor的窗口放到后台,在iOS应用中,你会得到&Waiting for game
view. Press &Play&&的消息。
点击Unity Editor中的Play。在你的iOS设备上,运行Unity Remote应用。从出现的列表中,选择你的电脑。如果你的电脑没有在列表中,试着在Unity Remote的IP设置中输入你电脑的IP地址。当Unity
Remote已经与你的电脑配对,你的iOS设备应该可以控制在Unity
Editor中运行的游戏。在设备上显示的分辨率不会很理想,但是这是最好的方法来快速展示你的游戏。但是,你应该也要偶尔为iOS构建项目,从
xcode加载这个游戏,这样你才可以在更实际的条件之下准确的测试游戏的物理效果。在iOS上测试这个游戏。你会发现在你的设备上没有办法移动你的玩家,这是因为你的left/right/up/down按键在iOS上不存在(虽然你仍然可以在你的mac上控制它)。下面,你将要实现一个摇杆功能来修正这点。
双倍的摇杆,双倍的快乐
对你来说幸运的是,Unity的标准的资源库中包括了实现摇杆功能的资源。选择AssetsImport PackageStandard Assets (Mobile)从包里导入相关的条目(如下面所看见的)。选择与与摇杆功能相关的指定项目。点击 Import。当导入过程结束,项目面板会包含一个名叫 Standard Assets(Mobile)的新的文件夹。在Unity4中,你可以看到导入的摇杆的脚本带着一个警告,就像这个样子(底部黄色的部分)要解决这个问题,在警告上双击。这会打开摇杆的脚本文件。把你的光标放在带有警告的那行:
gameObject.active =
修改这条语句为:
gameObject.SetActive(false);
现在当你切换到Unity Editor时,这条警告应该不存在了。了解了!首先添加双摇杆预制件到你的场景中。预制件是一个可复用的,并
且通常是需要被定製的GameObject。你可以从项目面板中将它拖出,给你的场景添加一个预制件,或者通过脚本以编程的方式添加。举例来说,你何以构
造一个预制件代表一个角色,然后以编程的方式添加多个角色到一个场景中。在你的项目面板中,打开Standard Assets (Mobile)Prefabs文件夹。将the Dual Joysticks prefab拖到你的Hierarchy视图中。点击Game视图,到游戏视图下,你可以看见这个摇杆:回到场景视图点击在Hierarchy视图的Dual Joysticks GameObject边上的三角。注意Dual Joysticks GameObject实际上有两个子GameObject组成。
这个过程叫做父子化,是用来建立摇杆父子GameObject关系的。父子化是非常有用的,你可以创建一个复合的GameObject,这个复合的
GameObject包含其他GameObject.
举例来说,你可以让左右摇杆在同一时间有效或失效,而且如果他们可以被视作一个简单的物件,通过脚本来完成这步就会相当容易。选择LeftJoystick &GameObject,注意有一个Joystick script组件关联在它上面。选择the RightJoystick GameObject,查看是否一样。Joystick
script探测附着在它上面的GUI纹理上的触摸事件,在特定的约束下来获取定位。举例来说,图形只在给定的范围内移动。这个脚本也归一化位置的输出,
让它在-1到+1之间。这让你可以在iOS环境下使用摇杆来作为Input.GetAxis()的替代。到这步,你已近在场景中放置了两个摇杆,但是它们还没有连接到你的英勇的小方块上来驱动输入。你将要改变脚本来分配右摇杆旋转角色的任务,而左摇杆来前后移动你的角色。修改MoveAround脚本来处理摇杆输入。打开脚本来编辑和添加公共变量代表移动和旋转摇杆(在其他变量的上面):
var moveJoystick : J
var rotateJoystick : J
然后添加一个新的函数来查看摇杆的位置,然后返回-1到+1之间的输出。就在Upate()函数后面添加。
function joyStickInput (joystick : Joystick) {
var absJoyPos = Vector2 (Mathf.Abs(joystick.position.x),
Mathf.Abs(joystick.position.y));
var xDirection = (joystick.position.x & 0) ? 1 : -1;
var yDirection = (joystick.position.y & 0) ? 1 : -1;
return ( ( absJoyPos.x & absJoyPos.y) ? absJoyPos.x * xDirection : absJoyPos.y * yDirection);
摇杆的输入是一个Vector2,有x和y分量。你使用x或y的绝对值中较大的那个作为输出。你使用摇杆的方向作为乘数来表示一个负值或正值。输出值的结果在-1到+1之间。修改Update()函数来处理来之Unity编辑器或一个iOS设备的输入:
function Update () {
var controller : CharacterController = GetComponent(CharacterController);
// Rotate around y - axis
var rotatePos = Input.GetAxis ("Horizontal") ?
Input.GetAxis ("Horizontal") : joyStickInput(rotateJoystick);
transform.Rotate(0, rotatePos * rotateSpeed, 0);
// Move forward / backward
var forward = transform.TransformDirection(Vector3.forward);
var movePos = Input.GetAxis ("Vertical") ?
Input.GetAxis ("Vertical") : joyStickInput(moveJoystick);
var curSpeed = speed * moveP
controller.SimpleMove(forward * curSpeed);
这个变换的Rotate()函数从左/右键(或A/D)键或旋转摇杆的输入获取输入。角色控制器的SimpleMove函数从上/下箭头(或W/S)键或者左摇杆的输入来得到输入。保存你脚本的修改。选择角色GameObject(这个方块),然后注意MoveAround脚本组件有两个针对移动摇杆和旋转摇杆的新的公共变量。这些变量当前还没有被赋值。保持角色GameObject仍然被选中,拖动左摇杆GameObject到移动摇杆变量上。拖动右摇杆GameObject到旋转摇杆变量上.(或者替代拖动,你可以使用每个变量边上的选择器,如之前指出的那样)点击Unity编辑器中的Player。在你的iOS设备上开启Unity Remote。测试摇杆的功能,然后确认你可以使用左摇杆前后移动,使用右摇杆来左右旋转。当你在你的iOS设备上移动摇杆的时候,你可以在Unity编辑器中看到摇杆在移动。
注意:你在这里看到的摇杆的图片也许被拉伸了。不要担心,在实际的设备上它们不会像这样显示的。
一个晴朗的天空
现在你已近改进了你的英勇的小方块的移动效果,那么来改善背景如何?到目前为止,角色都在一个沉闷和灰暗的世界中,是时候美化一下了.:]谢天谢地,这是非常简单的。Unity在标准的资源包中包含了这个让你可以创建天空的资源,添加植被和不同高度的地形。在这节中,你要用skybox组件添加一个天空。skybox是一个很大的方块对象,添加到你游戏的主摄像头上。当你添加了这个组件,你可以通过添加覆盖在方块上的材料,给这个方块穿上衣服,并被渲染来创建一个天空的效果。选择AssetsImport PackageSkyboxes来开始导入过程。选择Sunny2 Skybox.mat,然后点击导入。当导入完成,你的Project视图应该有一个新的Standard AssetsSkyboxes文件夹包括一个新的导入的资源。选择主摄像头对象,然后选择ComponentRenderingSkybox这个新的组件在Inspector中出现了。注意它有一个变量来代表材质。这里是你之前导入的skybox材料发挥作用的地方了。点击这个客制化的Skybox变量边上的小圆圈图标。一个选择材质的对话框会弹出来,列出你项目所有可以使用的材质。点击Sunny2 Skybox材质,然后关闭选择材质对话框。这个客制化的Skybox变量现在应该有一个Sunny2 Skybox材质付给它了。你的场景将奇迹般的改变了,显示你刚才添加的晴朗天空,你可以点击Game栏目来在Game视图中显示天空,或者点击Play按钮。太阳出来的!尽管它看上去阴沉沉的,这会鼓励你来给你的世界添加一些绿色的生命。
不要忘记添加绿色
切换回场景视图。你可以通过添加一个地形GameObject创建植被,然后添加一些材质(例如,草地)和一些对象(例如,树)。你不再需要平面(plane)GameObject,而terrain(地形)会取代地面的职责。在Hierarchy视图中右击plane GameObject,然后选择Delete.选择AssetsImport PackageTerrain Assets.点击Import来导入所有选中的内容。地形资源应该出现在你的标准资源文件夹下。你可以使用这个已导入的资源来改变地形GameObject的行为。选择TerrainCreate Terrain来添加一个地形GameObject到你的场景中。选择地形对象,然后使用Inspector改变它的位置到-00。这步将地形拉伸了到足够大,给你的角色有足够的空间来移动。地形(脚本)栏包括让你来装点你的地形的工具:选择绘画工具带来你可以工作的刷子:你将要用grass来绘制你的地形。点击Edit TexturesAdd Texture:在Add Terrain Texture对话框中,在Texture区域点击Select,选中Grass (Hill) texture,关闭Select Texture2D弹出窗口,然后点击Add:在你的场景视图中点击来绘制草地。要检查你的创作结果,点击Game栏目:美化总是这么容易吧!切换回场景视图 & 现在你将要绘制一些棕榈树!在地形(脚本)栏,选择Place Trees工具:点击Edit TreesAdd Tree:在Add Tree对话框中,点击Tree输入框边上的圆靶图标,选择棕榈树Game Object,然后点击Add:设置 Brush Size为20:通过点击你想要添加树木的地方来开始添加树到你的场景中。提示:当你放置树木的时候,放大场景然后移动场景。当你添加树木的时候,试图调整点光源的范围和高度来看见更多的场景。结束后,你的场景应该看上去像这个样子:Wow,相当不错!它开始看上去像一个真实的世界在那里。但是你的地形仍然看上有点平,不是吗?你可以很容易的添加一些高度变化到你的地形中。在地形(脚本)栏,选择最左面的工具来提升和降低地形的高度:设置Brush Size为20,然后在场景的试图中,点击玩家周围的2~3个点(不要太靠近,)来改变地形的高度。预览这个游戏,并在场景中四处走走。在场景中微调树木的数量,直到看上去合适,但是记住在你想要保留任何改变前,停止游戏。保存你的场景用Unity
Remote来测试你的项目,直到满意为止,在Xcode项目中构建它。选择FileBuild Settings,然后在 Build
Settings对话框中,点击Add
Current来添加Level_2场景。这个在场景中的新的场景会出现在构建清单中。不要选中Level_1场景,只要构建Level_2.如果被问起点击Build,选择替换前面的项目,然后加载Xcode项目。在你的iOS设备上部署和测试。不错吧,嗯?想象这会需要多久时间完成这些,如果你还在使用OpenGL :]
向哪里进发?
干的不错!你在拓展你的Unity技能上向前迈了一大步.:] 你的英勇的小方块也将会更加接近终点线。这里有一些从项目开始到目前为止的所有的代码下载:&, .在这份教程的最后部分,你将要在项目上添加游戏元素。通过添加玩家期待的钟声和口哨来给你的游戏增色。
阅读(...) 评论()CharacterController.isGrounded是否碰撞地面的问题???
.isGrounded就算是接触地面了,返回的也是在真和假之间。
求怎么解决!!!
我已经添加了重力的变种!!
要评论请先&或者&
自己顶一下!
CharacterController 已经封装了重力,所以你不用在添加重力了。是否接触到地面? 一般用来判断角色是否在空中。。。
:CharacterController 已经封装了重力,所以你不用在添加重力了。是否接触到地面? 一般用来判断角色是否在空中。。。 貌似是在CharacterController 的simplemove函数中封装了重力,但是在move函数中没有吧!!而且最最主要的就是当CharacterController 移动的时候isGrounded就是false只有静止的时候是true。我想要的是只要接触地面就返回true应该怎么做??谢谢
是啊,isGrounded碰撞到地面并且稳定站在地面上,true和false之间飘忽不定啊,没解决!!!!!!s:6]
刚才试验了一下,用射线碰撞代替CharacterController.isGrounded吧,谁知道这是UNITY3D的BUG,还是哪的毛病,希望高手能解决CharacterController.isGrounded飘忽不定的判断
&&怎么飘忽不定
一会是true ,一会是false,仔细观察一下角色,发现如果角色在Idle时来回晃悠就会出现这种情况,于是乎换个不晃悠的角色,发现真假不来回自动随机切换了,但始终是FALSE,晕,此时发现角色碰撞器和地面有一定的距离,在把角色手动把角色碰到地面上,在测试,角色又回到原来的位置,也就是始终和地面有一定距离,当人物走动时处于腾空状态。这种情况显得极不真实,最重要的是需要CharacterController.isGrounded 来判断跳跃啊,因为呈现的是假,所以跳跃不正常,只能用射线来代替这个句语了,但角色和地面脱空始终没解决!!!好累,打字太多了,手麻了
:一会是true ,一会是false,仔细观察一下角色,发现如果角色在Idle时来回晃悠就会出现这种情况,于是乎换个不晃悠的角色,发现真假不来回自动随机切换了,但始终是FALSE,晕,此时发现角色碰撞器和地面有一定的距离,在把角色手动把角色碰... 这两个字也会手麻,估计是美工出身charactorController有个skinWidth属性,这个值会导致碰撞器在和其他collider接触时保持一定间隙,不知道你有没有考虑到这个因素
确实如此,非常感谢!版主终究是版主,很厉害

我要回帖

更多关于 unity controller 的文章

 

随机推荐