C# 与另一个游戏对象';s位置

C# 与另一个游戏对象';s位置,c#,unity3d,gameobject,C#,Unity3d,Gameobject,我目前对自己制作的脚本有点问题。基本上,我想创建一个脚本,使其游戏对象(让我们命名为a)并遵循另一个游戏对象(命名为B)的位置。我知道一个简单的方法是把a变成B,但我不这么做有两个原因: 1) 我希望能够对a的运动应用平滑(其值可以更改); 2) 我希望能够随意跟随B的位置和/或旋转 这是我写的剧本: using UnityEngine; using System.Collections; public class FollowGameObject : MonoBehaviour { pub

我目前对自己制作的脚本有点问题。基本上,我想创建一个脚本,使其游戏对象(让我们命名为a)并遵循另一个游戏对象(命名为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)和另一个位置之间。从视觉上看,球体正在闪烁。 我尝试将平滑值设置为1(即A应始终位于B的位置/旋转)。我仍然看到一个闪烁的星星

有人能解释一下我做错了什么吗

编辑:似乎我在最后一个值中使用了错误的Lerp。我修改了脚本以使用速度值而不是平滑值,但在尝试创建一些平滑运动(使用较低的速度值)时仍然存在相同的问题。 我很难正确地解释这个问题。了解问题的最佳方式是亲自体验: 1) 创建包含地形和角色控制器的场景; 2) 将主摄像机设置为控制器的父对象(使其始终跟随控制器); 3) 使用渲染器(例如,球体)创建一个新游戏对象,该渲染器不作为任何其他游戏对象的父对象,但将以下脚本附加到它:

using UnityEngine;
使用系统集合

公共类FollowGameObject:MonoBehavior{

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=角色控制器游戏对象

m_FollowPosition=真

m_位置跟随速度=10

(其他参数值与此测试无关)


现在启动场景并移动角色控制器,我将看到球体在运动过程中闪烁,但如果停止移动,它将平滑地转到控制器

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

无论如何,尝试使用
Update
LateUpdate
而不是
FixedUpdate
或在
Project Settings=>Time>中选中
Fixed Timestep


另请阅读的答案,以了解有关
Update
FixedUpdate
之间差异的更多信息。我完全理解为什么不过度使用父对象和子对象。:)在启动方法中,使用两次m_UseOffsetPosition。我想你可能想在第二个if中使用m_UseOffsetRotation,这是用于旋转的。此外,m_旋转平滑=数学夹紧(m_位置平滑,0.0f,1.0f);不应该使用m_RotationSmoothing inside而不是m_PositionSmoothing?Maaann你是对的,对不起(这是在没有焦点的情况下复制/粘贴时发生的lol)。已修复,但问题仍然存在。我也在Unity论坛上发布了同样的问题,似乎我没有正确地使用Lerp(我不应该使用固定值作为最后一个参数,而是使用类似“Time.deltaTime*speed”的参数。我尝试了它,并用高速值(这与养育孩子的结果几乎相同)获得了更好的结果,但速度值较低(与应该给一些平滑)我仍然得到闪烁…我编辑了我的原始线程,在“编辑”后查看我正在测试的新脚本和自己体验问题的方式。