using UnityEngine; using System.Collections; using CharacterEngine.Controller; namespace CharacterEngine.Primitives { public sealed class CEPrimitives { #region Controller Globals public const int sweepResolution = 3; private static float gravity = -8.0f; public static float Gravity { get { return gravity; } set { gravity = value; } } #endregion #region Controller Variables private CEController controller; public readonly CECollider collider; private Vector3 velocity; public Vector3 Velocity { get { return velocity; } } public Transform transform { get { return controller.transform; } } #endregion #region Initializers & Constructors public CEPrimitives (CEController controller) { this.controller = controller; collider = new CECollider(controller.GetComponent()); } #endregion #region Steps /*Summary: Here in steps, there are the methods called in the UPDATES, that means that every step will be executed every frame. */ public void Step () { PhysicsStep(); } void PhysicsStep() { GetVelocity(); GravityStep(); CollisionStep(); ApplyVelocity(); Move(); } void GetVelocity() { } void GravityStep() { velocity.y += gravity * controller.weight * Time.deltaTime * 1.2f; velocity.x = -gravity * 0.5f; } void CollisionStep() { for (int i = 0; i < 5; i++) if (!CollideAndSlide()) break; } bool CollideAndSlide() { Vector3 oldPos = transform.position; Vector3 predictedPos = oldPos + velocity * Time.fixedDeltaTime; Vector3 correctedPos = predictedPos; RaycastHit hit = collider.SweepTest(velocity, velocity.magnitude * Time.fixedDeltaTime, controller.skinWidth); if (hit.collider == null) { return false; } Vector3 obstacleHitPoint = hit.point; Vector3 obstacleNormal = hit.normal; Vector3 obstacleTangent = Vector3.Cross(obstacleNormal, Vector3.forward); if (obstacleTangent.magnitude == 0) obstacleTangent = Vector3.Cross(obstacleNormal, Vector3.up); /* Plane obstaclePlane = new Plane(obstacleNormal, obstacleHitPoint); Ray velRay = new Ray(oldPos, velocity); float distanceFromPlane = 0.0f; obstaclePlane.Raycast(velRay, out distanceFromPlane); Vector3 vectorFromCenter = obstacleHitPoint - Coll.bounds.center ; */ correctedPos = oldPos + velocity.normalized * hit.distance; /* GameObject a = Instantiate(this.gameObject, correctedPos, transform.rotation) as GameObject; a.GetComponent().enabled = false; */ Vector3 epsilon = correctedPos - predictedPos; /* Vector3 normalForce = Vector3.Dot(obstacleNormal, oldVel) * obstacleNormal; newVel = oldVel - normalForce; //newVel = (oldVel.magnitude / newVel.magnitude) * newVel; */ Vector3 projectedForce = Vector3.Project(velocity, obstacleTangent); velocity = projectedForce; velocity.z = 0.0f; return true; } void ApplyVelocity() { Debug.DrawRay(transform.position, velocity); } void Move() { transform.position += velocity * Time.deltaTime; } #endregion } }