private static void GetCheckRay(MotionDirection side, CharacterMotorConfig config, Transform toMove, Vector3[] output, float index, float distance) { Vector3 sideDir = MotionUtil.ToVector(side); Vector3 origin = toMove.position; Vector3 direction = Vector3.zero; GetCheckValue(ref origin, ref direction, sideDir.x, config, index, Vector3.right, Vector3.up, distance); GetCheckValue(ref origin, ref direction, sideDir.y, config, index, Vector3.up, Vector3.right, distance); output[0] = origin; output[1] = origin + direction; }
public static void OnDrawGizmos(CharacterMotorConfig config, Transform toMove) { Gizmos.color = Color.green; foreach (MotionDirection side in SIDES) { for (int i = 0; i < config.sideCheckCount; i++) { GetCheckRay(side, config, toMove, RAY_BUFFER, i, config.gizmoDistance); Gizmos.DrawLine(RAY_BUFFER[0], RAY_BUFFER[1]); } } }
public static void Update(Transform toMove, CharacterMotorState state, CharacterMotorConfig config) { if (!state.isEnabled) { return; } Vector3 dir = getForcesDirection(state); dir = dir * Time.deltaTime; state.wasBlocked[MotionDirection.Up] = state.blocked[MotionDirection.Up]; state.wasBlocked[MotionDirection.Down] = state.blocked[MotionDirection.Down]; state.wasBlocked[MotionDirection.Left] = state.blocked[MotionDirection.Left]; state.wasBlocked[MotionDirection.Right] = state.blocked[MotionDirection.Right]; foreach (MotionDirection side in SIDES) { state.blocked[side] = false; Vector3 sideDir = MotionUtil.ToVector(side); var isMovingInSideXDir = Math.Sign(dir.x) == Math.Sign(sideDir.x); var isMovingInSideYDir = Math.Sign(dir.y) == Math.Sign(sideDir.y); if (!isMovingInSideXDir && !isMovingInSideYDir) { continue; } for (int i = 0; i < config.sideCheckCount; i++) { GetCheckRay(side, config, toMove, RAY_BUFFER, i, dir.magnitude); Vector3 direction = (RAY_BUFFER[1] - RAY_BUFFER[0]); float distance = GetBlockDistance(RAY_BUFFER[0], direction, config.layer); if (distance < float.MaxValue) { float canMove = Mathf.Max(0, distance - .01f); state.blocked[side] = true; dir.x = isMovingInSideXDir ? Mathf.Sign(dir.x) * Mathf.Min(canMove, Mathf.Abs(dir.x)) : dir.x; dir.y = isMovingInSideYDir ? Mathf.Sign(dir.y) * Mathf.Min(canMove, Mathf.Abs(dir.y)) : dir.y; break; } } } state.lastMotion = dir; toMove.position = toMove.position + dir; }
private static void GetCheckValue(ref Vector3 origin, ref Vector3 direction, float sideVal, CharacterMotorConfig config, float index, Vector3 dir, Vector3 opDir, float distance) { if (Mathf.Abs(sideVal) > .001f) { origin += dir * (config.offset * Mathf.Sign(sideVal)); direction = dir * (distance * Mathf.Sign(sideVal)); float increment = (config.offset * 2) / (config.sideCheckCount - 1); origin += opDir * (increment * index - config.offset); } }