【问题标题】:Camera shake on collision in unity 3dunity 3d 碰撞时相机抖动
【发布时间】:2013-03-31 19:22:14
【问题描述】:

http://answers.unity3d.com/questions/212189/camera-shake.html 我已经按照上面的问题的答案尝试让相机抖动适用于我的第一人称相机。但我试图修改它,使相机从一个看不见的碰撞盒中抖动。

到目前为止,我的相机抖动脚本如下所示;

public bool Shaking; 
private float ShakeDecay;
private float ShakeIntensity;   
private Vector3 OriginalPos;
private Quaternion OriginalRot;

void Start()
{
Shaking = false;   
}

void OnTriggerEnter(Collider collision)
{
if(collision.gameObject.name == "ShakeTrigger")
{
    DoShake();  
    Debug.Log("The camera trigger has hit");
}
}


void Update () 
{
if(ShakeIntensity > 0)
{
    transform.position = OriginalPos + Random.insideUnitSphere * ShakeIntensity;
    transform.rotation = new Quaternion(OriginalRot.x + Random.Range(-ShakeIntensity, ShakeIntensity)*.2f,
                              OriginalRot.y + Random.Range(-ShakeIntensity, ShakeIntensity)*.2f,
                              OriginalRot.z + Random.Range(-ShakeIntensity, ShakeIntensity)*.2f,
                              OriginalRot.w + Random.Range(-ShakeIntensity,     ShakeIntensity)*.2f);

   ShakeIntensity -= ShakeDecay;
}
else if (Shaking)
{
   Shaking = false;  
}

}


void OnGUI() {

 if (GUI.Button(new Rect(10, 200, 50, 30), "Shake"))
   DoShake();
   //Debug.Log("Shake");

}     

public void DoShake()
{
OriginalPos = transform.position;
OriginalRot = transform.rotation;

ShakeIntensity = 0.3f;
ShakeDecay = 0.02f;
Shaking = true;
}   

我知道代码可以通过 gui 按钮 100% 运行。此脚本附加到第一人称控制器上的相机。游戏中有一个带有 ShakeTrigger 标签的不可见碰撞框。但是,调试日志根本没有被调用,我不确定为什么。

如果有人需要更多信息,请告诉我。

提前致谢:)

【问题讨论】:

  • “隐形”盒子碰撞器是否检查了Is Trigger?如果不是,则永远不会调用 OnTriggerEnter。还要确保相机连接到刚体对撞机。 Here is a good link Unity 的碰撞矩阵。
  • 碰撞框确实选中了“触发”。我已经在附加到同一个盒子的单独脚本中有一些声音,效果很好。具有此脚本的相机是连接到第一人称控制器的“主相机”(我猜它已经具有刚体)。仍然没有让这个方法正常工作:(

标签: c# camera unity3d


【解决方案1】:

如果脚本已附加到您的相机,则 OnTriggerEnter 会查看相机以进行触发调用,而不是碰撞框。

您可以做的一件事是将 OnTriggerEnter 粘贴到一个新脚本中并将其放入碰撞框中。然后让它按照以下方式执行 SendMessage:

GameObject.Find("Camera").SendMessage("DoShake");

编辑:回答 Jerdak 的问题。

下面的代码将在 TriggerBox 内:

void Start()
{
    ...   
}

void OnTriggerEnter(Collider collision)
{
    if(collision.gameObject.name == "ShakeTrigger")
{
    GameObject.Find("Camera").SendMessage("DoShake");  
    Debug.Log("The camera trigger has hit");
}
}...

这将在相机内:

void Start()
{
    ...  
}

public void DoShake()
{
    OriginalPos = transform.position;
    OriginalRot = transform.rotation;

    ShakeIntensity = 0.3f;
    ShakeDecay = 0.02f;
    Shaking = true;
}... 

这样,triggerbox 负责检测触发器,并且只有在正确类型的物体通过它时才会向相机发送消息。然后相机负责进行抖动。

【讨论】:

  • 此代码运行良好,但会导致故障。一旦我走进触发盒,它会使相机抖动,但它会将相机移到第一人称控制器后面:L。然而,GUI 上的“摇动”按钮调用了相同的方法 (DoShake),不会导致同样的问题。
  • 刚刚开始工作。我已将“相机”引用更改为“主相机”(这是第一人称控制器上的名称)。没有意识到这应该是“播放器”。我已经读到 SendMessage 功能可能对性能不利,但我现在将使用它!非常感谢您的帮助:D
  • 这通常是个坏主意。 任何刚体或角色控制器进入该触发器都会导致相机抖动。当gameobject作为参数传入时,你为什么要进行全局查找也很不清楚:collision.gameObject。
  • @Jerdak 也许我没有说清楚......如果他将 onTriggerEnter 方法“按原样”粘贴到一个新脚本中,并简单地将DoShake() 替换为我的代码行,那么震动仍然只会在需要时触发。 GameObject.Find(..) 用于查找 Camera 对象(不是与触发盒碰撞的对象),因为 DoShake() 方法在相机脚本中。
  • @StevenMills 任何带有刚体的物体通过该触发器都会将 OnShake() 发送到相机。也许这就是 OP 的意图,目前尚不清楚。但是由于 OP 想要在相机通过触发器时触发抖动,因此相机是催化剂是理所当然的。在您的设置中,任何随机穿过触发器的敌方 NPC 都会导致 OnShake()。
【解决方案2】:

要在碰撞或触发时摇动您的相机,您需要首先制作您的摇动功能,您也可以从其他脚本调用该功能

类似

public class ShakeCamera : MonoBehavior
{
    public bool canShake;
    
    private void Update()
    {
       if(canShake)
       DoShake()
    }
    public void DoShake()
    {
        // Shake Logic
    }
    public void StartShake()
    {
       canShake = true;
    }
    public void StopShake()
    {
       canShake = false;
    }
}

每当您触发目标对象时,您都可以从其他脚本中调用它

    public class TriggerScript: MonoBehavior
        {
            public ShakeCamera shakeCamera;

            private void Start()
            {
                shakeCamera = FindObjectOfType<ShakeCamera>();
            }

            void OnTriggerEnter(Collider collision)
            {
                 if(collision.gameObject.tag == "targetTag")// Change Tag accroding to your requirement
                    {
                      
                        cameraShake.StartShake();
                    } 
             }
            void OnTriggerExit(Collider collision)
            {
                 if(collision.gameObject.tag == "targetTag")// Change Tag accroding to your requirement
                    {
                        cameraShake.StopShake();
                    } 
             }
        }

我正在为您附上一个参考视频,它可能会帮助您更好地抖动相机。希望对您有所帮助。

你可以参考我制作的这个视频https://youtu.be/9X_JXexwfR4

【讨论】:

  • 当链接到您自己的网站或内容(或您附属的内容)时,您must disclose your affiliation in the answer 以免被视为垃圾邮件。根据 Stack Exchange 政策,在您的用户名中包含与 URL 相同的文本或在您的个人资料中提及它不被视为充分披露。
【解决方案3】:

如果您已设置刚体,则将插值从无更改为插值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-18
    • 1970-01-01
    • 2020-11-11
    相关资源
    最近更新 更多