应该遵循另一个GameObject的位置的脚本问题

时间:2015-02-11 02:45:50

标签: c# unity3d gameobject

我目前对我制作的脚本有一点问题。基本上,我想创建一个脚本,使其GameObject(让它命名为A)并遵循另一个GameObject(名为B)的位置。我知道一个简单的方法是父母A到B,但我没有这样做有两个原因: 1)我希望能够在A的运动中应用平滑(我可以改变它的值); 2)我希望能够随意跟随B的位置和/或轮换。

这是我写的脚本:

using UnityEngine;
using System.Collections;

public class FollowGameObject : MonoBehaviour {

public GameObject m_GameObjectToFollow;
public bool m_FollowPosition;
public bool m_FollowRotation;
public float m_PositionSmoothing;
public float m_RotationSmoothing;
// Should not be changed once set
public bool m_UseOffsetPosition;
public bool m_UseOffsetRotation;
private Vector3 m_PositionOffset;
private Quaternion m_RotationOffset;

void Start () {

    m_PositionSmoothing = Mathf.Clamp(m_PositionSmoothing, 0.0f, 1.0f);
    m_RotationSmoothing = Mathf.Clamp(m_RotationSmoothing, 0.0f, 1.0f);

    if (m_UseOffsetPosition)
    {
        m_PositionOffset = transform.position - m_GameObjectToFollow.transform.position;
    } else {
        m_PositionOffset = Vector3.zero;
    }

    if (m_UseOffsetRotation)
    {
        m_RotationOffset = transform.rotation * Quaternion.Inverse(m_GameObjectToFollow.transform.rotation);
    } else {
        m_RotationOffset = Quaternion.identity;
    }

}

void FixedUpdate () {

    if (m_FollowPosition) {
        Vector3 goalPosition = m_GameObjectToFollow.transform.position + m_PositionOffset;
        transform.position = Vector3.Lerp(transform.position, goalPosition, m_PositionSmoothing);
        //transform.Translate(newPosition - transform.position, Space.World);
    }

    if (m_FollowRotation) {
        Quaternion goalRotation = m_GameObjectToFollow.transform.rotation * m_RotationOffset;
        transform.rotation = Quaternion.Lerp(transform.rotation, goalRotation, m_RotationSmoothing);
    }

}

我希望代码很容易理解,如果不随意问的话。 在任何情况下,一旦我将此脚本附加到A并将其m_GameObjectToFollow属性分配给B(B是角色控制器的父级,我将球形渲染器作为A的父级,这样我就可以看到它是否正确地跟随B),我注意到A确实跟随B,但是我看到它的位置(通过球体渲染器)是"波动"在"右边"之间位置(B' s)和另一个。在视觉上,球体闪烁。 我尝试将平滑值设为1(即A应始终位于B' s位置/旋转)。我仍然看到一个闪烁。

有人可以向我解释我做错了吗?

编辑:好像我用Lerp错误的方式使用它的最后一个值。我修改了脚本以使用速度值而不是平滑值,但是当我尝试创建一些平滑的移动(速度值较低)时,仍然会出现同样的问题。 我有麻烦正确解释问题。查看问题的最佳方法是亲自体验: 1)创建一个包含地形和角色控制器的场景; 2)将主摄像机输入控制器(以便始终跟随它); 3)使用渲染器(例如,球体)创建一个新的GameObject,而不是任何其他GameObject的父级,但是将以下脚本附加到它:

using UnityEngine;

使用System.Collections;

public class FollowGameObject:MonoBehaviour {

public GameObject m_GameObjectToFollow;
public bool m_FollowPosition;
public bool m_FollowRotation;
// Betzeen 0 and 1. 1 means that a complete unsmoothed follow
public float m_PositionFollowSpeed;
public float m_RotationFollowSpeed;
// Should not be changed once set
public bool m_UseOffsetPosition;
public bool m_UseOffsetRotation;
private Vector3 m_PositionOffset;
private Quaternion m_RotationOffset;

void Start () {

    if (m_UseOffsetPosition)
    {
        m_PositionOffset = transform.position - m_GameObjectToFollow.transform.position;
    } else {
        m_PositionOffset = Vector3.zero;
    }

    if (m_UseOffsetRotation)
    {
        m_RotationOffset = transform.rotation * Quaternion.Inverse(m_GameObjectToFollow.transform.rotation);
    } else {
        m_RotationOffset = Quaternion.identity;
    }

}

void Update () {

    if (m_FollowPosition) {
        Vector3 goalPosition = m_GameObjectToFollow.transform.position + m_PositionOffset;
        transform.position = Vector3.Slerp(transform.position, goalPosition, Time.deltaTime * m_PositionFollowSpeed);
    }

    if (m_FollowRotation) {
        Quaternion goalRotation = m_GameObjectToFollow.transform.rotation * m_RotationOffset;
        transform.rotation = Quaternion.Slerp(transform.rotation, goalRotation, Time.deltaTime * m_RotationFollowSpeed);
    }

}

}

用: m_GameObjectToFollow =角色控制器GameObject;

m_FollowPosition = true;

m_PositionFollowSpeed = 10;

(其他参数值对此测试无关紧要)

现在启动场景并移动角色控制器,我会看到球体在运动过程中闪烁,但是如果你停止移动它会顺利地进入控制器。

1 个答案:

答案 0 :(得分:0)

您正在使用FixedUpdate。这样做有什么特别的理由吗?

无论如何,请尝试使用UpdateLateUpdate代替FixedUpdate,或在Fixed Timestep中查看Project Settings => Time

另请阅读this question的答案,了解有关UpdateFixedUpdate之间差异的详情。