/// <summary> /// returns the surface type at a raycast hit point. detects surfaces by /// surface identifier, texture / material, atlas texture and terrain /// </summary> public static vp_SurfaceType GetSurfaceType(RaycastHit hit) { // TIP: if you have problems getting the correct footstep- or projectile // FX to spawn on an object, uncomment all the debug lines in this method // to see what 'GetSurfaceType' detects (if anything) vp_SurfaceType s = null; // --- surface identifier --- // detect objects with a surface identifier vp_SurfaceIdentifier i = GetSurfaceIdentifier(hit); if (i != null) { s = i.SurfaceType; //Debug.Log("hit a surface identifier '" + s .name + "' @ " + Time.time); if (s != null) { return(s); } } // --- simple surface --- // detect objects with a single material and no texture regions s = GetSimpleSurface(hit); if (s != null) { //Debug.Log("hit a single material object with surface '" + s.name + "' @ " + Time.time); return(s); } // --- complex surface --- // detect objects with texture regions (atlases) and / or multiple materials s = GetComplexSurface(hit); if (s != null) { //Debug.Log("hit a multi-material (or uv region fallback) object with surface '" + s.name + "' @ " + Time.time); return(s); } // --- terrain surface --- // check the terrain for a surface if all of the above failed s = GetTerrainSurface(hit); if (s != null) { //Debug.Log("hit a terrain object with surface '" + s.name + "' @ " + Time.time); return(s); } // --- no surface --- // failed to find a surface based on the raycast hit //Debug.Log("failed to find a surface on object '"+hit.transform.gameObject.name+"'"); return(null); }
/// <summary> /// /// </summary> protected override void Start() { base.Start(); SetPosition(Transform.position); // this will initialize some position variables // if set, automagically sets up a trigger for interacting with // incoming rigidbodies if (PhysicsHasCollisionTrigger) { m_Trigger = new GameObject("Trigger"); m_Trigger.transform.parent = m_Transform; m_Trigger.layer = vp_Layer.LocalPlayer; m_Trigger.transform.localPosition = Vector3.zero; m_TriggerCollider = m_Trigger.AddComponent <CapsuleCollider>(); m_TriggerCollider.isTrigger = true; m_TriggerCollider.radius = CharacterController.radius + SkinWidth; m_TriggerCollider.height = CharacterController.height + (SkinWidth * 2.0f); m_TriggerCollider.center = CharacterController.center; m_Trigger.gameObject.AddComponent <vp_DamageTransfer>(); // if we have a SurfaceIdentifier, copy it along with its values onto the trigger. // this will make the trigger emit the same fx as the controller when hit by bullets if (SurfaceIdentifier != null) { vp_Timer.In(0.05f, () => // wait atleast one frame for this to take effect properly { vp_SurfaceIdentifier triggerSurfaceIdentifier = m_Trigger.gameObject.AddComponent <vp_SurfaceIdentifier>(); triggerSurfaceIdentifier.SurfaceType = SurfaceIdentifier.SurfaceType; triggerSurfaceIdentifier.AllowDecals = SurfaceIdentifier.AllowDecals; }); } } }
/// <summary> /// updates controller motion according to detected collisions /// against objects below, above and around the controller /// </summary> protected virtual void UpdateCollisions() { // --- respond to ground collision --- if ((m_GroundHit.transform != null) && (m_GroundHit.transform != m_LastGroundHit.transform)) { // store fall impact if (!MotorFreeFly) m_FallImpact = -m_HighestFallSpeed * Time.timeScale; else m_FallImpact = -(CharacterController.velocity.y * 0.01f) * Time.timeScale; // sync camera y pos m_SmoothPosition.y = Transform.position.y; // deflect the controller sideways under some circumstances DeflectDownForce(); m_HighestFallSpeed = 0.0f; // transmit fall impact to the player Player.FallImpact.Send(m_FallImpact); // reset all the jump variables m_MotorThrottle.y = 0.0f; m_MotorJumpForceAcc = 0.0f; m_MotorJumpForceHoldSkipFrames = 0; // detect and store moving platforms if (m_GroundHit.collider.gameObject.layer == vp_Layer.MovableObject) { m_Platform = m_GroundHit.transform; m_LastPlatformAngle = m_Platform.eulerAngles.y; } else m_Platform = null; // detect if there is terrain and store it if so Terrain ter = m_GroundHit.transform.GetComponent<Terrain>(); if (ter != null) m_CurrentTerrain = ter; else m_CurrentTerrain = null; vp_SurfaceIdentifier sid = m_GroundHit.transform.GetComponent<vp_SurfaceIdentifier>(); if (sid != null) m_CurrentSurface = sid; else m_CurrentSurface = null; } else m_FallImpact = 0.0f; // store ground hit for detecting fall impact and loss of grounding // in next frame m_LastGroundHit = m_GroundHit; // --- respond to ceiling collision --- // deflect forces that push the controller upward, in order to prevent // getting stuck in ceilings if ((m_PredictedPos.y > Transform.position.y) && (m_ExternalForce.y > 0 || m_MotorThrottle.y > 0)) DeflectUpForce(); // --- respond to wall collision --- // if the controller didn't end up at the predicted position, some // external object has blocked its way, so deflect the movement forces // to avoid getting stuck at walls if ((m_PredictedPos.x != Transform.position.x) || (m_PredictedPos.z != Transform.position.z) && (m_ExternalForce != Vector3.zero)) DeflectHorizontalForce(); }
/// <summary> /// hooks up the component object as the inspector target /// </summary> public virtual void OnEnable() { m_Component = (vp_SurfaceIdentifier)target; }
/// <summary> /// updates controller motion according to detected collisions /// against objects below, above and around the controller /// </summary> protected override void UpdateCollisions() { base.UpdateCollisions(); if (m_OnNewGround) { // deflect the controller sideways under some circumstances if (m_WasFalling) { DeflectDownForce(); // sync camera y pos m_SmoothPosition.y = Transform.position.y; // reset all the jump variables m_MotorThrottle.y = 0.0f; m_MotorJumpForceAcc = 0.0f; m_MotorJumpForceHoldSkipFrames = 0; #region Cygnus stuffs GameController.InvokeLanded(this, Player.GetComponent <PlayerController>()); #endregion } // detect and store moving platforms // // TODO:should be in base class for AI if (m_GroundHit.collider.gameObject.layer == vp_Layer.MovingPlatform) { m_Platform = m_GroundHit.transform; m_LastPlatformAngle = m_Platform.eulerAngles.y; } else { m_Platform = null; } // detect if there is terrain and store it if so // // TODO:should be in base class for AI and remote players Terrain ter = m_GroundHitTransform.GetComponent <Terrain>(); if (ter != null) { m_CurrentTerrain = ter; } else { m_CurrentTerrain = null; } vp_SurfaceIdentifier sid = m_GroundHitTransform.GetComponent <vp_SurfaceIdentifier>(); if (sid != null) { m_CurrentSurface = sid; } else { m_CurrentSurface = null; } } // --- respond to ceiling collision --- // deflect forces that push the controller upward, in order to prevent // getting stuck in ceilings if ((m_PredictedPos.y > Transform.position.y) && (m_ExternalForce.y > 0 || m_MotorThrottle.y > 0)) { DeflectUpForce(); } // --- respond to wall collision --- // if the controller didn't end up at the predicted position, some // external object has blocked its way, so deflect the movement forces // to avoid getting stuck at walls if ((m_PredictedPos.x != Transform.position.x) || (m_PredictedPos.z != Transform.position.z) && (m_ExternalForce != Vector3.zero)) { DeflectHorizontalForce(); } }
/// <summary> /// updates controller motion according to detected collisions /// against objects below, above and around the controller /// </summary> protected override void UpdateCollisions() { base.UpdateCollisions(); if (m_OnNewGround) { // deflect the controller sideways under some circumstances if (m_WasFalling) { DeflectDownForce(); // sync camera y pos m_SmoothPosition.y = Transform.position.y; // reset all the jump variables m_MotorThrottle.y = 0.0f; m_MotorJumpForceAcc = 0.0f; m_MotorJumpForceHoldSkipFrames = 0; } // detect and store moving platforms // TODO: should be in base class for AI if (m_GroundHit.collider.gameObject.layer == vp_Layer.MovingPlatform) { m_Platform = m_GroundHit.transform; m_LastPlatformAngle = m_Platform.eulerAngles.y; } else m_Platform = null; // detect if there is terrain and store it if so // TODO: should be in base class for AI and remote players Terrain ter = m_GroundHitTransform.GetComponent<Terrain>(); if (ter != null) m_CurrentTerrain = ter; else m_CurrentTerrain = null; vp_SurfaceIdentifier sid = m_GroundHitTransform.GetComponent<vp_SurfaceIdentifier>(); if (sid != null) m_CurrentSurface = sid; else m_CurrentSurface = null; } // --- respond to ceiling collision --- // deflect forces that push the controller upward, in order to prevent // getting stuck in ceilings if ((m_PredictedPos.y > Transform.position.y) && (m_ExternalForce.y > 0 || m_MotorThrottle.y > 0)) DeflectUpForce(); // --- respond to wall collision --- // if the controller didn't end up at the predicted position, some // external object has blocked its way, so deflect the movement forces // to avoid getting stuck at walls if ((m_PredictedPos.x != Transform.position.x) || (m_PredictedPos.z != Transform.position.z) && (m_ExternalForce != Vector3.zero)) DeflectHorizontalForce(); }