private bool CheckGround(CharacterControllerMotor motor, Transform transform) { var controller = motor.CharacterController; var worldCenter = transform.position + controller.center; var lowPoint = worldCenter - new Vector3(0, controller.height * 0.5f, 0); Profiler.BeginSample("RaycastNonAlloc"); var layerMask = CPhysicSettings.PhysicInteractionLayerMask; var rayLength = Physics.RaycastNonAlloc(lowPoint, Vector3.down, s_RaycastHits, 0.0001f, layerMask); Profiler.EndSample(); for (int i = 0; i != rayLength; i++) { var ray = s_RaycastHits[i]; if (ray.transform == transform) { continue; } var velocityToAdd = ray.point - lowPoint; CPhysicSettings.Active.SetGlobalCollision(motor.gameObject, true); motor.MoveBy(velocityToAdd); CPhysicSettings.Active.SetGlobalCollision(motor.gameObject, false); return(true); } return(false); }
private Vector3 ProbeGround(CharacterControllerMotor motor, Transform transform, Vector3 previousDirection, float maxAngle, float globalMaxAngle) { var controller = motor.CharacterController; var worldCenter = transform.position + controller.center; var lowPoint = worldCenter - new Vector3(0, controller.height * 0.5f, 0); var highPoint = lowPoint + new Vector3(0, controller.height, 0); Profiler.BeginSample("RaycastNonAlloc"); var layerMask = CPhysicSettings.PhysicInteractionLayerMask; var rayLength = Physics.RaycastNonAlloc(lowPoint, Vector3.down, s_RaycastHits, controller.stepOffset, layerMask); Profiler.EndSample(); if (previousDirection == Vector3.zero) { previousDirection = Vector3.up; } var highestAngle = 0f; var highestDir = previousDirection; var highestY = float.MinValue; for (int i = 0; i != rayLength; i++) { var ray = s_RaycastHits[i]; if (ray.transform == transform) { continue; } //ray.normal = RepairHitSurfaceNormal(ray); var angle = Vector3.Angle(previousDirection, ray.normal); if (angle > highestAngle) { highestAngle = angle; highestDir = ray.normal; } if (angle > maxAngle || Vector3.Angle(Vector3.up, ray.normal) > globalMaxAngle && highestY > ray.point.y) { continue; } var velocityToAdd = ray.point - lowPoint; CPhysicSettings.Active.SetGlobalCollision(motor.gameObject, true); motor.MoveBy(velocityToAdd); CPhysicSettings.Active.SetGlobalCollision(motor.gameObject, false); highestY = ray.point.y; motor.IsGroundForcedThisFrame = true; } return(highestDir); }
void Start() { velocity = Vector3.zero; angularVelocity = Vector3.zero; xform = transform; motor = GetComponent<CharacterControllerMotor>(); oldPosition = xform.position; oldRotation = xform.rotation.eulerAngles; }
void Start() { velocity = Vector3.zero; angularVelocity = Vector3.zero; xform = transform; motor = GetComponent <CharacterControllerMotor>(); oldPosition = xform.position; oldRotation = xform.rotation.eulerAngles; }
private bool OnControllerHasHitACollider(ControllerColliderHit hit, float plannedDistance, Vector3 oldPos, CharacterControllerMotor motor, Transform transform, ref Vector3 correctedVelocity) { var controller = motor.CharacterController; var worldCenter = transform.position + controller.center; var lowPoint = worldCenter - new Vector3(0, controller.height * 0.5f, 0); var highPoint = lowPoint + new Vector3(0, controller.height, 0); var angle = Vector3.Angle(hit.normal, Vector3.down); if (hit.point.y > lowPoint.y + controller.stepOffset) { var flatVelocity = correctedVelocity.ToGrid(1); var flatNormal = hit.normal.ToGrid(1); var undesiredMotion = flatNormal * Vector3.Dot(flatVelocity, flatNormal); var desiredMotion = flatVelocity - undesiredMotion; var desiredY = desiredMotion.y; desiredMotion.y = 0; desiredMotion = Vector3.ClampMagnitude(desiredMotion, flatVelocity.magnitude); desiredMotion.y = correctedVelocity.y; correctedVelocity = desiredMotion; // Floor if ((controller.collisionFlags == CollisionFlags.Above || (int)controller.collisionFlags == 3) && angle < 90f && correctedVelocity.y > 0) { correctedVelocity.y = desiredY; } return(true); } return(false); }
private Vector3 GetAngleDir(CharacterControllerMotor motor, Transform transform) { var controller = motor.CharacterController; var height = controller.height; var radius = controller.radius; var worldCenter = transform.position + controller.center; var lowPoint = worldCenter - new Vector3(0, height * 0.5f, 0); var highPoint = lowPoint + new Vector3(0, height, 0); var distance = height * 0.25f + 0.1f + (controller.skinWidth * 4); var layerMask = CPhysicSettings.PhysicInteractionLayerMask; var rayLength = Physics.CapsuleCastNonAlloc(worldCenter, highPoint, radius, Vector3.down, s_RaycastHits, distance, layerMask); var smallestAngle = float.MaxValue; var smallestDir = Vector3.down; if (rayLength > 0) { motor.IsGroundForcedThisFrame = true; } for (int i = 0; i != rayLength; i++) { var ray = s_RaycastHits[i]; Physics.Raycast(ray.point + Vector3.up * 0.01f, Vector3.down, out ray, ray.distance + 0.02f); var normal = ray.normal; //var normal = RepairHitSurfaceNormal(ray); var angle = Vector3.Angle(Vector3.up, normal); Debug.DrawRay(ray.point, normal, Color.green, 5); if (angle < smallestAngle) { smallestAngle = angle; smallestDir = normal; } } return(smallestDir); }
public static bool OnGround(CharacterControllerMotor controllerMotor, StVelocity velocity) { return(velocity.Value.y <= 0 && controllerMotor.IsGrounded(CPhysicSettings.PhysicInteractionLayerMask)); }
private bool ProcessItem ( ref Entity entity, ref StVelocity velocity, ref DefStDodgeOnGroundSettings setting, ref DefStRunInput runInput, ref DefStDodgeInput input, ref DefStWallDodgeProcessData process, ref DefStDodgeOnGroundProcessData groundProcess, CharacterControllerMotor motor ) { var action = input.State != InputState.None && !MvUtils.OnGround(motor, velocity) && Time.time > process.TimeBeforeNextWD; DiffuseCommand(m_CmdDoDodge, m_CmdDoDodgeResult, action, CmdState.Begin); if (!m_CmdDoDodgeResult.GetComponentData <EntityCommandResult>().AsBool()) { DiffuseCommand(m_CmdDoDodge, m_CmdDoDodgeResult, action, CmdState.End); return(false); } var originalVelocity = velocity.Value; var fwd = motor.transform.forward; var pos = motor.transform.position + new Vector3(0, motor.CharacterController.stepOffset + 0.1f); var rot = motor.transform.rotation; var rd = motor.CharacterController.radius + 0.075f; var sw = motor.CharacterController.skinWidth + 0.025f; var height = motor.CharacterController.height - motor.CharacterController.stepOffset; var subheight = (height * 0.75f) - 0.005f; CPhysicSettings.Active.SetGlobalCollision(motor.gameObject, false); var direction = (Vector3)SrtComputeDirection(fwd, rot, runInput.Direction); direction = (velocity.Value.ToGrid(1).normalized + direction * 2).normalized; var rayTrace = UtilityWallRayTrace.RayTrace(ref direction, ref pos, ref rd, ref sw, ref height, ref subheight, motor.CharacterController); CPhysicSettings.Active.SetGlobalCollision(motor.gameObject, true); var success = rayTrace.normal != Vector3.zero && Mathf.Abs(rayTrace.normal.y) < 0.2f; if (success) { rayTrace.normal = rayTrace.normal.ToGrid(1).normalized; var reflected = (Vector3.Reflect(direction, rayTrace.normal) + rayTrace.normal).normalized; var oldY = velocity.Value.y; var dirInertie = (reflected * (velocity.Value.magnitude + 1)) + rayTrace.normal * 3.5f; dirInertie = RaycastUtilities.SlideVelocityNoYChange(velocity.Value, rayTrace.normal) + rayTrace.normal * 10; var minSpeed = Mathf.Max(velocity.Value.ToGrid(1).magnitude + setting.AdditiveSpeed, setting.MinSpeed); velocity.Value = dirInertie.ToGrid(1).normalized *(minSpeed); velocity.Value.y = Mathf.Max(oldY + 2, 0); process.TimeBeforeNextWD = Time.time + DefaultCooldown; input.TimeBeforeResetState = -1f; input.State = InputState.None; groundProcess.CooldownBeforeNextDodge = 0.25f; //groundProcess.InertieDelta = 0.5f; groundProcess.Direction = dirInertie.normalized; BroadcastNewEntity(PostUpdateCommands, true); PostUpdateCommands.AddComponent(new DefStWallJumpEvent(Time.time, Time.frameCount, entity, originalVelocity, rayTrace.normal)); } DiffuseCommand(m_CmdDoDodge, m_CmdDoDodgeResult, action, CmdState.End); return(success); }