2016-03-05 64 views
0

移動了從玩家控制器:我如何防止玩家通過牆壁在Unity3d

using UnityEngine; 
using UnityEngine.Networking; 
using System.Collections; 

[RequireComponent(typeof(NetworkIdentity))] 
public class PlayerController : NetworkBehaviour { 
    public Vector3 size = new Vector3(1, 1, 1); 
    public float speed = 10; 
    public float rotateSpeed = 9; 

    private Transform _transform; 
    private Map _map; 
    private BoxCollider _collider; 
    private bool _active = false; 

    private Vector3 _lastPosition; 
    private bool _isGrounded = false; 

    void Start() { 
     _transform = transform; 
     Messenger.AddListener ("MAP_LOADED", OnMapLoaded); 

     _transform.localPosition = new Vector3 (-100, -100, -100); 

     gameObject.name = "Player " + gameObject.GetComponent<NetworkIdentity>().netId.Value; 
     _collider = gameObject.GetComponent<BoxCollider>(); 
     _map = GameObject.Find ("Map").GetComponent<Map>(); 

     _collider.size = size; 
    } 

    void OnMapLoaded() { 
     if (isLocalPlayer) { 
      // Hook up the camera 
      PlayerCamera cam = Camera.main.GetComponent<PlayerCamera>(); 
      cam.target = transform; 

      // Move the player to the it's spawn location 
      _transform.localPosition = _map.GetPlayerSpawn(); 
     } 

     // Set the player as active 
     _active = true; 
    } 

    void Update() { 
     if (!isLocalPlayer || !_active) { 
      return; 
     } 

     _lastPosition = _transform.position; 

     float transAmount = speed * Time.deltaTime; 
     float rotateAmount = rotateSpeed * Time.deltaTime; 

     if (Input.GetKey ("up")) { 
      transform.Translate (0, 0, transAmount); 
     } 
     if (Input.GetKey ("down")) { 
      transform.Translate (0, 0, -transAmount); 
     } 
     if (Input.GetKey ("left")) { 
      transform.Rotate (0, -rotateAmount, 0); 
     } 
     if (Input.GetKey ("right")) { 
      transform.Rotate (0, rotateAmount, 0); 
     } 

     if (!_isGrounded) { 
      Vector3 down = _transform.TransformDirection(Vector3.down); 
      _transform.position += down * Time.deltaTime * _map.gravity; 
     } 
    } 

    void FixedUpdate() { 
     // 
     // Check what is below us 
     // 
     Vector3 down = _transform.TransformDirection(Vector3.down); 
     RaycastHit[] hits; 
     hits = Physics.RaycastAll(_transform.position, down, size.y + 0.001f); 

     _isGrounded = false; 
     foreach (RaycastHit hit in hits) { 
      if (hit.collider.gameObject.tag.ToUpper() == "GROUND") { 
       _isGrounded = true; 
      } 
     } 
    } 

    void OnTriggerEnter(Collider collider) { 
     Debug.Log ("Triggered by " + collider.gameObject.tag.ToUpper()); 
     if (collider.gameObject.tag.ToUpper() == "GROUND") { 
      transform.position = _lastPosition; 
     } 
    } 

} 

Update我走了用戶的輸入和移動變換左右。在FixedUpdate我正在檢查玩家是否在地上並正確設置旗幟。最後在OnTriggerEnter我正在檢查,看看我是否試圖通過任何東西。

如果在OnTriggerEnter我打了一些東西,我嘗試將玩家的位置恢復到良好的位置,但這並未發生。我的猜測是因爲_lastPosition不是我所期望的。

有沒有更好的方法來做到這一點?

回答