飞跃运动第一人称控制器

时间:2014-12-18 03:53:48

标签: c# unity3d collision-detection

我目前正在使用Unity开发一款飞跃动作游戏。 当我只是用手势来取代使用键盘的传统第一人称控制时。我可以用跳跃运动控制器穿过墙壁。但是当我使用键盘时,它会停在墙上。我在墙上添加了一个碰撞盒。但我仍然无法解决问题。

下面是我在C#中的Leap Characters Controller脚本

using UnityEngine;
using System.Collections;
using Leap;

public class LeapCharacterController : MonoBehaviour {

    Controller m_leapController;
    float m_lastBlastTime = 0.0f;

    GameObject m_carriedObject;
    bool m_handOpenThisFrame = false;
    bool m_handOpenLastFrame = false;

    // Use this for initialization
    void Start () {
        m_leapController = new Controller();
    }

    // gets the hand furthest away from the user (closest to the screen).
    Hand GetForeMostHand() {
        Frame f = m_leapController.Frame();
        Hand foremostHand = null;
        float zMax = -float.MaxValue;
        for(int i = 0; i < f.Hands.Count; ++i) {
            float palmZ = f.Hands[i].PalmPosition.ToUnityScaled().z;
            if (palmZ > zMax) {
                zMax = palmZ;
                foremostHand = f.Hands[i];
            }
        }

        return foremostHand;
    }

    void OnHandOpen(Hand h) {
        m_carriedObject = null;
    }

    void OnHandClose(Hand h) {
        // look for an object to pick up.
        RaycastHit hit;
        if(Physics.SphereCast(new Ray(transform.position + transform.forward * 2.0f, transform.forward), 2.0f, out hit)) {
            m_carriedObject = hit.collider.gameObject;
        }
    }

    bool IsHandOpen(Hand h) {
        return h.Fingers.Count > 1; 
    }

    // processes character camera look based on hand position.
    void ProcessLook(Hand hand) {
        float handX = hand.PalmPosition.ToUnityScaled().x;
        transform.RotateAround(Vector3.up, handX * 0.30f);
    }

    void MoveCharacter(Hand hand) {
        if (hand.PalmPosition.ToUnityScaled().z > 0) {
            transform.position += transform.forward * 0.1f;
        }

        if (hand.PalmPosition.ToUnityScaled().z < -1.0f) {
            transform.position -= transform.forward * 0.04f;
        }
    }

    // Determines if any of the hand open/close functions should be called.
    void HandCallbacks(Hand h) {
        if (m_handOpenThisFrame && m_handOpenLastFrame == false) {
            OnHandOpen(h);
        }

        if (m_handOpenThisFrame == false && m_handOpenLastFrame == true) {
            OnHandClose(h); 
        }
    }

    // if we're carrying an object, perform the logic needed to move the object
    // with us as we walk (or pull it toward us if it's far away).
    void MoveCarriedObject() {
        if (m_carriedObject != null) {
            Vector3 targetPos = transform.position + new Vector3(transform.forward.x, 0, transform.forward.z) * 5.0f;
            Vector3 deltaVec = targetPos - m_carriedObject.transform.position;
            if (deltaVec.magnitude > 0.1f) {
                m_carriedObject.rigidbody.velocity = (deltaVec) * 10.0f;
            } else {
                m_carriedObject.rigidbody.velocity = Vector3.zero;
            }
        }
    }

    void FixedUpdate () {
        Hand foremostHand = GetForeMostHand();
        if (foremostHand != null) {
            m_handOpenThisFrame = IsHandOpen(foremostHand);
            ProcessLook(foremostHand);
            MoveCharacter(foremostHand);
            HandCallbacks(foremostHand);
            MoveCarriedObject();
        }
        m_handOpenLastFrame = m_handOpenThisFrame;
    }
}

1 个答案:

答案 0 :(得分:1)

void MoveCharacter(Hand hand) {
        if (hand.PalmPosition.ToUnityScaled().z > 0) {
            transform.position += transform.forward * 0.1f;
        }

        if (hand.PalmPosition.ToUnityScaled().z < -1.0f) {
            transform.position -= transform.forward * 0.04f;
        }
    }

您正在直接修改变换的位置,而不进行任何形式的碰撞检测。如果你想使用unity的碰撞器和物理引擎,你需要使用刚体进行移动,或者如果你想坚持直接设置变换的位置,你需要实现自己的碰撞检测代码(可能是光线投射或其他一些)。

此问题在统一文档中介绍:http://docs.unity3d.com/ScriptReference/Rigidbody.MovePosition.html

并且有一个如何在学习网站上进行视频,该网站通过刚体在这里查看运动:http://unity3d.com/earn/tutorials/projects/space-shooter/moving-the-player