Reputation: 21512
I've got the following player controller:
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;
}
}
}
In Update
I'm taking the user's input and moving the transform around. In FixedUpdate
I'm checking to see if the player is on the ground and setting a flag appropriately. And finally in OnTriggerEnter
I'm checking to see if I'm trying to go through anything.
If in OnTriggerEnter
I hit something I try to set the player's position back to a good one, but that's not happening. My guess is because _lastPosition
isn't what I'm expecting it to be.
Is there a better way to do this?
Upvotes: 0
Views: 1238
Reputation: 1570
Use rigidbody.Move(position) instead of transform.Translate(position).
Note: Using transform.translate causing performance issues and you must handle collision detection manually.
Upvotes: 1