首页 > 解决方案 > 当我尝试转换此播放器控制器时,它只是重置为原始位置

问题描述

这是我现在使用的播放器控制器的简化版本,它仍然会产生下面解释的错误:

using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;
using UnityStandardAssets.Utility;
using Random = UnityEngine.Random;

namespace UnityStandardAssets.Characters.FirstPerson
{
    [RequireComponent(typeof (CharacterController))]
    public class FirstPersonController : MonoBehaviour
    {
        [SerializeField] private float m_RunSpeed;

        private CharacterController m_CharacterController;

        // Use this for initialization
        private void Start()
        {
            m_CharacterController = GetComponent<CharacterController>();
        }

        private void FixedUpdate()
        {
            Vector3 move = Vector3.right * m_RunSpeed;
            m_CharacterController.Move(move * Time.fixedDeltaTime);
        } 
    }
}

我正在使用标准资产脚本,并且试图让脚本将玩家传送到不同的地方。当我尝试移动播放器时,它会移动到该位置一帧,然后又回到它的位置。

player.transform = new Vector3(1,2,3);
// works as expected, but then next frame, player's
// position is back to where it was before

标签: c#unity3d

解决方案


出现此问题是因为Move可能无法读取transform.position.

这个问题已经在官方的 Unity 问题跟踪器上报告,并且在那里也发布了一个解决方案:

这里的问题是在物理设置中禁用了自动同步变换,因此characterController.Move()不一定知道变换设置的新姿势,除非在 transform.position 和之间发生了 aFixedUpdatePhysics.Simulate()调用CC.Move()

要解决这个问题,要么在物理设置中启用自动同步转换,要么Physics.SyncTransforms在调用之前手动同步Move()

因此,您可以通过编辑来解决您的问题,FixedUpdate以便它调用Physics.SyncTransformsbefore Move,如下所示:

using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;
using UnityStandardAssets.Utility;
using Random = UnityEngine.Random;

namespace UnityStandardAssets.Characters.FirstPerson
{
    [RequireComponent(typeof (CharacterController))]
    public class FirstPersonController : MonoBehaviour
    {
        [SerializeField] private float m_RunSpeed;

        private CharacterController m_CharacterController;

        // Use this for initialization
        private void Start()
        {
            m_CharacterController = GetComponent<CharacterController>();
        }

        private void FixedUpdate()
        {
            Vector3 move = Vector3.right * m_RunSpeed;

            Physics.SyncTransforms();
            m_CharacterController.Move(move * Time.fixedDeltaTime);
        } 
    }
}

推荐阅读