我被建议在这个链接中使用State Machine第一个答案:
但我现在还不确定是否需要。我认为我的问题应该更容易解决,而且我也不了解如何使用状态机。
第一部分,每当我在角色周围移动鼠标时,使用RaycastHit
和LookAt
正在旋转并面向鼠标位置。当我每次玩家走路并到达目标点(鼠标点击位置)时,这个部分应该是我的默认空闲状态。
澄清一下,其他两个州是Idle
和Walking
;两者都是使用HumanoidWalk
和HumanoidIdle
的动画状态。当我点击鼠标按钮时,播放器将会#34; Walk"朝着目标;单击鼠标位置,当它到达那里时,它将进入Idle
状态。此外,它将再次返回LookAt
模式,这样我就可以移动鼠标,角色将旋转/面向鼠标位置。
然而,我现在得到的是当角色到达鼠标点击时,他开始不间断地旋转。如果我移动鼠标,播放器将开始行走并跟随鼠标移动。这不是我想要的。
我尝试更改1.0f
,2.0f
和3.0f
的距离进行测试,但它并没有解决任何问题。
运行游戏时的主Idle
状态以及当角色到达鼠标点击位置时,应该以某种方式与此部分结合:
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit) && hit.collider.name != "ThirdPersonController")
{
transform.LookAt(hit.point);
}
else
{
transform.LookAt(ray.GetPoint(100));
}
处于空闲状态:
_animator.CrossFade("Idle", 0);
这是剧本:
using UnityEngine;
using System.Collections;
public class MoveObjects : MonoBehaviour {
private Animator _animator;
void Start()
{
_animator = GetComponent<Animator>();
_animator.CrossFade("Idle", 0);
}
void Update()
{
MovePlayerWithMouse();
}
private void MovePlayerWithMouse()
{
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit) && hit.collider.name != "ThirdPersonController")
{
transform.LookAt(hit.point);
}
else
{
transform.LookAt(ray.GetPoint(100));
}
if (Input.GetMouseButtonDown(0))
{
if ((transform.position - hit.point).magnitude < 1.0f)
{
_animator.CrossFade("Idle", 0);
}
else
{
_animator.CrossFade("Walk", 0);
}
}
}
答案 0 :(得分:1)
看起来玩家似乎没有&#34;知道&#34;它已经到了这一点。如果它试图看到自身内部的一个点,它会不规则地旋转,试图朝着它的脚点旋转。
我建议查看字符何时到达目的地的条件,并调试fsm中的当前状态是否在到达目的地时发生变化,以及它是否在&#34;空闲&#34;当你期望它时。如果不是,我会修改条件。
另外,不要对光线投射使用对撞机字符串比较,它会变得缓慢而繁琐。我将有一个单独的控制器(在游戏循环执行顺序菜单中首先执行),它将碰撞矩阵设置为忽略的内容。
https://docs.unity3d.com/Manual/LayerBasedCollision.html
这是编辑菜单,但可以在游戏中访问。在这个控制器中,我会设置图层名称,并在此处添加碰撞异常。
如果你需要一个&#34;一个关闭&#34;忽略冲突的例外,使用以下格式的图层掩码: 1&lt;&lt; layerNumber。
您也可以在代码中从layertag获取图层编号。这基本上通过使用单个整数来表示是否应该忽略每个层的冲突(最多32个层,因为int有32位)。每个位可以是1(忽略)或0(用于检测该层上的冲突)。您可以使用按位&amp;组合多个图层掩码。 (它基本上组合了每个anded整数中的任何1)以获得您想要忽略的所有图层的最终结果。