Created
September 4, 2015 17:37
-
-
Save elringus/8533773f99db56f66232 to your computer and use it in GitHub Desktop.
PlayerCollisionTester
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
#if UNITY_EDITOR | |
using UnityEditor; | |
#endif | |
using System.Collections; | |
using System.Collections.Generic; | |
public class vgPlayerCollisionTester : vgMonoBehaviour | |
{ | |
public float checkDistance = 10.0f; | |
public float checksPerMeter = 5.0f; | |
public float warningAngleTolerance = 5.0f; | |
public int checksPerFrame = 500; | |
private MeshFilter dynamicMesh = null; | |
public List<Vector3> newVertices = new List<Vector3>(); | |
public List<int> newTriangles = new List<int>(); | |
public List<Vector2> newUV = new List<Vector2>(); | |
private static Vector2 uvRed = new Vector2(0.125f, 1.0f); | |
private static Vector2 uvGreen = new Vector2(0.625f, 1.0f); | |
private static Vector2 uvWhite = new Vector2(0.875f, 1.0f); | |
public GameObject playerObject; | |
private float maxAngle = 90.0f; | |
private int checkTracker = 0; | |
// Use this for initialization | |
void OnEnable() | |
{ | |
MeshRenderer renderer = gameObject.GetComponent<MeshRenderer>(); | |
if( renderer == null ) | |
{ | |
renderer = gameObject.AddComponent<MeshRenderer>(); | |
} | |
dynamicMesh = gameObject.GetComponent<MeshFilter>(); | |
if( dynamicMesh == null ) | |
{ | |
dynamicMesh = gameObject.AddComponent<MeshFilter>(); | |
} | |
playerObject = transform.parent.gameObject; | |
transform.ClearLocals(); | |
renderer.material.shader = Shader.Find("Particles/Additive"); | |
renderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; | |
Texture debugTexture = Resources.Load<Texture>("DebugTextures/debug_color_rygw_4x4"); | |
renderer.material.mainTexture = debugTexture; | |
float checkHalfDistance = checkDistance * 0.5f; | |
Vector3 startCorner = new Vector3( -checkHalfDistance, 0.0f, -1.0f); | |
float strideDistance = 1.0f / checksPerMeter; | |
int checkNumber = Mathf.RoundToInt( checkDistance / strideDistance ); | |
Vector3 xVector = new Vector3(strideDistance, 0.0f, 0.0f); | |
Vector3 zVector = new Vector3(0.0f, 0.0f, strideDistance); | |
newTriangles.Clear(); | |
newVertices.Clear(); | |
newUV.Clear(); | |
for( int xIndex = 0; xIndex < checkNumber; ++xIndex ) | |
{ | |
for( int zIndex = 0; zIndex < checkNumber; ++zIndex ) | |
{ | |
newVertices.Add( startCorner + (xVector * xIndex) + (zVector * zIndex) ); | |
newUV.Add(uvWhite); | |
if( xIndex > 0 && zIndex > 0 ) | |
{ | |
int baseIndex = newVertices.Count - 1; | |
newTriangles.Add(baseIndex); | |
newTriangles.Add(baseIndex - checkNumber); | |
newTriangles.Add(baseIndex - 1); | |
newTriangles.Add(baseIndex - checkNumber); | |
newTriangles.Add(baseIndex - checkNumber - 1); | |
newTriangles.Add(baseIndex - 1); | |
} | |
} | |
} | |
maxAngle = playerObject.GetComponent<CharacterController>().slopeLimit; | |
} | |
// Update is called once per frame | |
void Update () | |
{ | |
Mesh mesh = dynamicMesh.mesh; | |
if( checkTracker >= newVertices.Count ) | |
{ | |
checkTracker = 0; | |
} | |
int maxIndexThisFrame = checkTracker + checksPerFrame; | |
for( int i = checkTracker; i < newVertices.Count && i < maxIndexThisFrame; ++i ) | |
{ | |
++checkTracker; | |
Vector3 worldPosition = newVertices[i]; | |
worldPosition = gameObject.transform.TransformPoint(worldPosition); | |
worldPosition.y = playerObject.transform.position.y; | |
worldPosition += Vector3.up * 1.0f; | |
RaycastHit hitInfo; | |
LayerMask playerLayerMask = vgPhysicsManager.GetPhysicsMask(playerObject); | |
float roofCheckDistance = 2.0f; | |
float floorCheckDistance = 10.0f; | |
if( Physics.SphereCast(worldPosition, 0.4f, Vector3.up, out hitInfo, roofCheckDistance, playerLayerMask) ) | |
{ | |
worldPosition = hitInfo.point - (Vector3.up * 0.1f); | |
floorCheckDistance += hitInfo.distance; | |
} | |
else | |
{ | |
worldPosition += Vector3.up * roofCheckDistance; | |
floorCheckDistance += roofCheckDistance; | |
} | |
if( Physics.SphereCast(worldPosition, 0.4f, Vector3.down, out hitInfo, floorCheckDistance, playerLayerMask) ) | |
{ | |
Vector3 vertPoint = newVertices[i]; | |
vertPoint.y = hitInfo.point.y - gameObject.transform.position.y; | |
vertPoint.y += playerObject.GetComponent<CharacterController>().radius; | |
newVertices[i] = vertPoint; | |
float groundAngle = Vector3.Angle(hitInfo.normal, Vector3.up); | |
if( hitInfo.collider.gameObject.tag == "Player" || hitInfo.collider.gameObject.tag == "MainCamera" ) | |
{ | |
vertPoint.y = gameObject.transform.localPosition.y; | |
newVertices[i] = vertPoint; | |
newUV[i] = uvGreen; | |
} | |
else if( groundAngle > maxAngle ) | |
{ | |
newUV[i] = uvRed; | |
} | |
else if( maxAngle - groundAngle < warningAngleTolerance ) | |
{ | |
Vector2 currentUV = newUV[i]; | |
currentUV.y = 0.0f; | |
newUV[i] = currentUV; | |
} | |
else | |
{ | |
newUV[i] = uvGreen; | |
} | |
} | |
else | |
{ | |
Vector3 vertPoint = newVertices[i]; | |
vertPoint.y = 0.0f; | |
newVertices[i] = vertPoint; | |
newUV[i] = uvWhite; | |
} | |
} | |
mesh.Clear(); | |
mesh.vertices = newVertices.ToArray(); | |
mesh.triangles = newTriangles.ToArray(); | |
mesh.uv = newUV.ToArray(); | |
mesh.Optimize(); | |
mesh.RecalculateNormals(); | |
} | |
#if UNITY_EDITOR | |
[MenuItem("Window/Video Game/Add Player Collision Tester", false, vgMath.vgWindowPriority)] | |
public static void Init() | |
{ | |
if( !Application.isPlaying ) | |
{ | |
return; | |
} | |
GameObject playerObject = vgPlayerController.playerGameObject; | |
if( playerObject != null ) | |
{ | |
GameObject collisionTester = new GameObject( "Collision Tester" ); | |
collisionTester.SetActive(false); | |
collisionTester.AddComponent<vgPlayerCollisionTester>(); | |
collisionTester.transform.parent = playerObject.transform; | |
collisionTester.SetActive(true); | |
} | |
} | |
#endif | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment