public void UpdateLedgeDetectorState(Vector3 pos)
    {
        const float bodyRadius = PlayerConstants.BODY_RADIUS;
        const float distance   = 0.13f;

        // TODO: Add comments, some of them clever.
        RaycastHit?ceilingHit = CylinderPhysics.CircleCast(
            pos,
            bodyRadius,
            BIG_NUMBER,
            Vector3.up
            );
        float ceilingHeight = ceilingHit?.distance ?? BIG_NUMBER;

        Vector3 echoStart = pos + (Vector3.up * ceilingHeight);

        RaycastHit?echoHit = CylinderPhysics.CircleCast(
            echoStart,
            bodyRadius + distance,
            BIG_NUMBER,
            Vector3.down
            );

        LedgePresent = echoHit.HasValue;
        if (LedgePresent)
        {
            DebugDisplay.DrawPoint(Color.green, echoHit.Value.point);
            LastLedgeHeight = echoHit.Value.point.y - pos.y;
        }
    }
Пример #2
0
    public void UpdateWallState(Vector3 pos)
    {
        // Do a capsule overlap to see if we're touching a wall
        var wallHits = CylinderPhysics.OverlapCylinder(
            pos,
            PlayerConstants.BODY_RADIUS + WALL_CHECK_DIST,
            PlayerConstants.BODY_HEIGHT
            );

        IsTouchingWall = wallHits.Any(c => c.transform != this.transform);

        if (!IsTouchingWall)
        {
            return;
        }

        // Do some cheaty box-casting to find the normal of the wall we're touching.
        var lastNormal = FindWallNormal(pos);

        if (!lastNormal.HasValue)
        {
            IsTouchingWall = false;
            return;
        }
        LastWallNormal = lastNormal.Value;
    }
Пример #3
0
 /// <summary>
 /// Returns a raycast hit for the ground we're above,
 /// or null if we're in the air.
 /// </summary>
 /// <returns></returns>
 private RaycastHit?GetGround(Vector3 pos)
 {
     return(CylinderPhysics.CircleCast(
                pos + (Vector3.up * RAYCAST_OFFSET),
                PlayerConstants.BODY_RADIUS,
                RAYCAST_DISTANCE,
                Vector3.down,
                QueryTriggerInteraction.Ignore
                ));
 }
Пример #4
0
 public bool CheckBonkingHead(Vector3 pos)
 {
     return(CylinderPhysics.CylinderCast(
                pos + (Vector3.up * PlayerConstants.BODY_HEIGHT),
                PlayerConstants.BODY_RADIUS,
                GROUND_DETECTOR_THICKNESS,
                Vector3.up,
                GROUND_DETECTOR_THICKNESS / 2
                ));
 }
    public static void VisualizeCylinderCast(
        Vector3 origin,
        float radius,
        float height,
        Vector3 direction,
        float maxDistance = Mathf.Infinity
        )
    {
        Vector3 visualizationSize = Vector3.one * 1;
        Vector3 start             = origin - (visualizationSize / 2);
        Vector3 end = origin + (visualizationSize / 2);

        // Create a bunch of voxels.  They'll act as "probes".
        Vector3 voxelSize = Vector3.one * 0.1f;
        var     voxels    = new HashSet <GameObject>();

        for (float x = start.x; x < end.x; x += voxelSize.x)
        {
            for (float y = start.y; y < end.y; y += voxelSize.y)
            {
                for (float z = start.z; z < end.z; z += voxelSize.z)
                {
                    var pos = new Vector3(x, y, z);

                    // Skip the positions that are obviously deep inside
                    float distance = Vector3.Cross(direction, pos - origin).magnitude;
                    if (distance < radius)
                    {
                        continue;
                    }

                    // Either create the voxel, or get one from the pool.
                    GameObject voxel;
                    int        i = voxels.Count;
                    if (i < _voxelPool.Count)
                    {
                        voxel = _voxelPool[i];
                    }
                    else
                    {
                        voxel = GameObject.CreatePrimitive(PrimitiveType.Cube);
                        GameObject.Destroy(voxel.GetComponent <Renderer>());
                        _voxelPool.Add(voxel);
                    }

                    // Move it to the correct place
                    voxel.transform.position   = pos;
                    voxel.transform.localScale = voxelSize;

                    var collider = voxel.GetComponent <BoxCollider>();
                    collider.isTrigger = true;

                    voxels.Add(voxel);
                }
            }
        }

        // Destroy all voxels in the pool that aren't being used.
        while (_voxelPool.Count > voxels.Count)
        {
            int i = _voxelPool.Count - 1;
            GameObject.Destroy(_voxelPool[i]);
            _voxelPool.RemoveAt(i);
        }

        // Do the cylinder cast
        var hits = CylinderPhysics.CylinderCastAll(origin, radius, height, direction, maxDistance);

        // Draw a gizmo for every voxel that's in the cylinder cast
        foreach (var h in hits)
        {
            if (!voxels.Contains(h.collider.gameObject))
            {
                continue;
            }

            DebugDrawCube(Color.blue, h.collider.gameObject.transform.position, voxelSize);
        }
    }