void Update() { velocity = velocityMethod == VelocityMethod.Rigidbody ? rb.velocity : nma.velocity; var flattenedVelocity = velocity.Flatten().normalized; if (velocity.Flatten().magnitude > velocityDeadZone) { var velocityRotation = Quaternion.LookRotation(flattenedVelocity); var targetRotation = Quaternion.Slerp(velocityRotation, velocityRotation * GetTiltRotation(), Time.deltaTime * tiltDamping); transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * rotationDamping); } if (!animator || animatorParameterMap == null) { return; } radius = Mathf.Clamp(velocity.Flatten().magnitude, 0.1f, 1f); speedOffset += velocity.Flatten().magnitude / radius * Time.deltaTime; if (flattenedVelocity.magnitude < velocityDeadZone) { animator.SetFloat(animatorParameterMap[CharacterParam.Idle], 1f); animator.SetFloat(animatorParameterMap[CharacterParam.Walk], 0f); animator.SetFloat(animatorParameterMap[CharacterParam.Run], 0f); } else { UpdateAnimator(); } }
private static void CalculateAngles(Vector3 anglePosition, Vector3 guideDirection, Vector3 incomingDirection, ICollection <Measurement> measurements) { guideDirection = guideDirection.Flatten().normalized; incomingDirection = incomingDirection.Flatten().normalized; var angleSize = Vector3.Angle(guideDirection, incomingDirection); var angleDirection = Vector3.Normalize(guideDirection + incomingDirection); var otherAngleSize = 180f - angleSize; var otherAngleDirection = Vector3.Normalize(-guideDirection + incomingDirection); if (otherAngleSize < angleSize) { Util.Swap(ref angleSize, ref otherAngleSize); Util.Swap(ref angleDirection, ref otherAngleDirection); } measurements.Add(new AngleMeasurement(angleSize, anglePosition, angleDirection, MeasurementFlags.Primary | MeasurementFlags.Guide)); if (Mathf.Abs(angleSize - 180f) < 0.5f || Mathf.Abs(otherAngleSize - 180f) < 0.5f) { return; } measurements.Add(new AngleMeasurement(otherAngleSize, anglePosition, otherAngleDirection, MeasurementFlags.Secondary | MeasurementFlags.Guide)); }
public void Move() { RaycastHit hitInfo; if (Physics.Raycast(transform.position, CurrentHeading.Flatten().normalized, out hitInfo, SightDistance, terrainLayerMask)) { CurrentHeading = Vector3.Lerp(CurrentHeading, (transform.position - hitInfo.point).normalized, Time.deltaTime * 5f * UnityEngine.Random.Range(0.5f, 1.5f)); } rb.velocity = Vector3.Lerp(rb.velocity + Vector3.down * 0.25f, CurrentHeading.Flatten().normalized *Speed *speedMultiplier, Time.deltaTime * timeMultiplier); if (rb.velocity.magnitude > Speed) { rb.velocity *= (Speed / rb.velocity.magnitude); } areaOfEffectRing.position = transform.position; areaOfEffectRing.forward = CurrentHeading.normalized; }
private static bool CanNodeBranchInDirection(ushort nodeId, Vector3 direction) { var closestSegmentId = NetNodeUtility.GetClosestSegmentId(nodeId, direction); var exitDirection = NetNodeUtility.GetSegmentExitDirection(nodeId, closestSegmentId); var exitAngle = Vector3Extensions.GetSignedAngleBetween(direction.Flatten(), exitDirection.Flatten(), Vector3.up); return(Mathf.Abs(exitAngle) >= 45f); }
private bool IsVisible(Vector3 viewPosition, float viewDistance) { float scale = endlessTerrain.Scale; viewDistance *= scale; Vector2 size = ((Vector2)terrainData.size) * scale; Bounds bounds = new Bounds(gameObject.transform.position + (new Vector3(size.x, 0f, size.y) / 2f), new Vector3(size.x, 5f, size.y)); Vector3 testPoint = bounds.ClosestPoint(viewPosition.Flatten()); return(Vector3.Distance(testPoint, viewPosition) < viewDistance); }
private void TrackDistance(bool reset = false) { if (reset) { wayPoints.Clear(); } else if (wayPoints.Count == numWayPoints) { wayPoints.Dequeue(); } Vector2 pos = targetPosition.Flatten(); wayPoints.Enqueue(pos); distanceCovered = Mathf.Min(1f, Vector2.Distance((Vector2)wayPoints.Peek(), pos) / (searchRadius * wayPoints.Count)); }
public void AddTower(TowerType towerType, Vector3 position) { GameObject prefab; if (towerType == TowerType.CLOCKWISE) { prefab = ClockwiseTowerPrefab; } else if (towerType == TowerType.COUNTER_CLOCKWISE) { prefab = CounterClockwiseTowerPrefab; } else { throw new ArgumentException("Unrecognized tower type: " + towerType.ToString(), "towerType"); } GameObject.Instantiate(prefab, position.Flatten(), Quaternion.identity); }
/// <summary> /// Gets the angle from start arm around axis /// </summary> /// <param name="forward">the end of angle</param> /// <param name="startArm">the start of angle</param> /// <param name="axis">the axis of angle</param> /// <returns>the signed angle from startArm to forward around axis</returns> public static float SignedAngleFromAxis(this Vector3 forward, Vector3 startArm, int axis) => forward.Flatten(axis).SignedAngle(startArm, VectorFrom(i => i == axis ? 1 : 0));
public bool IsCarAffected(Vector3 carPosition) { return(Vector3.SqrMagnitude(carPosition.Flatten() - transform.position.Flatten()) <= Radius * Radius); }
public static void CalculateAngles(ushort nodeId, Vector3 direction, ICollection <Measurement> measurements) { direction = direction.Flatten(); var node = NetManager.instance.m_nodes.m_buffer[nodeId]; var existingSegments = NetNodeUtility.GetNodeSegmentIds(node); if (existingSegments.Count == 0) { return; } var nearestLeftAngle = 360f; ushort nearestLeftSegmentId = 0; var nearestLeftNormal = Vector3.zero; var nearestRightAngle = 360f; ushort nearestRightSegmentId = 0; var nearestRightNormal = Vector3.zero; for (var i = 0; i < existingSegments.Count; i++) { var s = NetManager.instance.m_segments.m_buffer[existingSegments[i]]; var d = s.m_startNode == nodeId ? s.m_startDirection : s.m_endDirection; d = d.Flatten(); var angle = Vector3Extensions.GetClockwiseAngleBetween(-d, direction, Vector3.up); var leftAngle = 360f - angle; var rightAngle = angle; var n = Vector3.Normalize(direction + d); if (leftAngle < nearestLeftAngle) { nearestLeftAngle = leftAngle; nearestLeftSegmentId = existingSegments[i]; nearestLeftNormal = Quaternion.AngleAxis(leftAngle * 0.5f, Vector3.up) * direction; } if (rightAngle < nearestRightAngle) { nearestRightAngle = rightAngle; nearestRightSegmentId = existingSegments[i]; nearestRightNormal = Quaternion.AngleAxis(rightAngle * -0.5f, Vector3.up) * direction; } } // When both angles are 180, only show the one on the right. if (Math.Abs(nearestLeftAngle - 180f) < 0.25f && Math.Abs(nearestRightAngle - 180f) < 0.25f) { measurements.Add(new AngleMeasurement(nearestRightAngle, node.m_position, nearestRightNormal, MeasurementFlags.Primary)); return; } var leftFlags = nearestRightSegmentId > 0 ? (nearestLeftAngle < nearestRightAngle ? MeasurementFlags.Primary : MeasurementFlags.Secondary) : MeasurementFlags.Secondary; var rightFlags = nearestLeftSegmentId > 0 ? (nearestRightAngle <= nearestLeftAngle ? MeasurementFlags.Primary : MeasurementFlags.Secondary) : MeasurementFlags.Secondary; if (nearestLeftSegmentId > 0) { measurements.Add(new AngleMeasurement(nearestLeftAngle, node.m_position, nearestLeftNormal, leftFlags)); } if (nearestRightSegmentId > 0) { measurements.Add(new AngleMeasurement(nearestRightAngle, node.m_position, nearestRightNormal, rightFlags)); } }
public static void CalculateAngles(ushort nodeId, Vector3 direction, ICollection<Measurement> measurements) { direction = direction.Flatten(); var node = NetManager.instance.m_nodes.m_buffer[nodeId]; var existingSegments = NetNodeUtility.GetNodeSegmentIds(node); if (existingSegments.Count == 0) { return; } var nearestLeftAngle = 360f; ushort nearestLeftSegmentId = 0; var nearestLeftNormal = Vector3.zero; var nearestRightAngle = 360f; ushort nearestRightSegmentId = 0; var nearestRightNormal = Vector3.zero; for (var i = 0; i < existingSegments.Count; i++) { var s = NetManager.instance.m_segments.m_buffer[existingSegments[i]]; var d = s.m_startNode == nodeId ? s.m_startDirection : s.m_endDirection; d = d.Flatten(); var angle = Vector3Extensions.GetClockwiseAngleBetween(-d, direction, Vector3.up); var leftAngle = 360f - angle; var rightAngle = angle; var n = Vector3.Normalize(direction + d); if (leftAngle < nearestLeftAngle) { nearestLeftAngle = leftAngle; nearestLeftSegmentId = existingSegments[i]; nearestLeftNormal = Quaternion.AngleAxis(leftAngle*0.5f, Vector3.up)*direction; } if (rightAngle < nearestRightAngle) { nearestRightAngle = rightAngle; nearestRightSegmentId = existingSegments[i]; nearestRightNormal = Quaternion.AngleAxis(rightAngle*-0.5f, Vector3.up)*direction; } } // When both angles are 180, only show the one on the right. if (Math.Abs(nearestLeftAngle - 180f) < 0.25f && Math.Abs(nearestRightAngle - 180f) < 0.25f) { measurements.Add(new AngleMeasurement(nearestRightAngle, node.m_position, nearestRightNormal, MeasurementFlags.Primary)); return; } var leftFlags = nearestRightSegmentId > 0 ? (nearestLeftAngle < nearestRightAngle ? MeasurementFlags.Primary : MeasurementFlags.Secondary) : MeasurementFlags.Secondary; var rightFlags = nearestLeftSegmentId > 0 ? (nearestRightAngle <= nearestLeftAngle ? MeasurementFlags.Primary : MeasurementFlags.Secondary) : MeasurementFlags.Secondary; if (nearestLeftSegmentId > 0) { measurements.Add(new AngleMeasurement(nearestLeftAngle, node.m_position, nearestLeftNormal, leftFlags)); } if (nearestRightSegmentId > 0) { measurements.Add(new AngleMeasurement(nearestRightAngle, node.m_position, nearestRightNormal, rightFlags)); } }
/// <inheritdoc /> public IReadOnlyCollection <float> Flatten() { return(TopCorner.Flatten().Concat(BottomCorner.Flatten()).ToArray()); }
private static void TestLine(NetInfo netInfo, Vector3 startPoint, Vector3 endPoint, Vector3 l1, Vector3 l2, IList <GuideLine> lines, ushort segmentId = 0, ushort nodeId = 0) { var p = Util.LineIntersectionPoint(startPoint.xz(), endPoint.xz(), l1.xz(), l2.xz()); // Lines never meet, discard if (!p.HasValue) { return; } var intersect = new Vector3(p.Value.x, 0, p.Value.y); var intersectDistanceSqr = Vector3Extensions.DistanceSquared(intersect, endPoint.Flatten()); // Discard if intersect is silly distance away if (intersectDistanceSqr > Settings.MaxGuideLineQueryDistanceSqr) { return; } var guideDirection = l1.Flatten().DirectionTo(l2.Flatten()); var intersectDirection = l1.Flatten().DirectionTo(intersect); // Ignore guides in the wrong direction if (Mathf.Abs(Vector3Extensions.GetSignedAngleBetween(guideDirection, intersectDirection, Vector3.up)) > 90f) { return; } intersect.y = TerrainManager.instance.SampleRawHeightSmooth(intersect); var intersectDistance = Mathf.Sqrt(intersectDistanceSqr); var line = new GuideLine(l1, intersect, netInfo.m_halfWidth * 2f, intersectDistance, segmentId); int index; if (IsDuplicate(lines, line, out index)) { var d = lines[index]; // If a duplicate, check if it is closer than the duplicate if (Vector3Extensions.DistanceSquared(d.Origin, endPoint) > Vector3Extensions.DistanceSquared(l1, endPoint)) { lines[index] = line; } return; } // Check for intersection with existing nodes var ra = Vector3.Cross(guideDirection, Vector3.up); var quad = new Quad3(l1 + ra, l1 - ra, intersect + ra, intersect - ra); if (NetManager.instance.OverlapQuad(Quad2.XZ(quad), 0, 1280f, ItemClass.CollisionType.Undefined, netInfo.m_class.m_layer, nodeId, 0, segmentId)) { return; } lines.Add(line); }
private static void TestLine(NetInfo netInfo, Vector3 startPoint, Vector3 endPoint, Vector3 l1, Vector3 l2, IList<GuideLine> lines, ushort segmentId = 0, ushort nodeId = 0) { var p = Util.LineIntersectionPoint(startPoint.xz(), endPoint.xz(), l1.xz(), l2.xz()); // Lines never meet, discard if (!p.HasValue) return; var intersect = new Vector3(p.Value.x, 0, p.Value.y); var intersectDistanceSqr = Vector3Extensions.DistanceSquared(intersect, endPoint.Flatten()); // Discard if intersect is silly distance away if (intersectDistanceSqr > Settings.MaxGuideLineQueryDistanceSqr) return; var guideDirection = l1.Flatten().DirectionTo(l2.Flatten()); var intersectDirection = l1.Flatten().DirectionTo(intersect); // Ignore guides in the wrong direction if (Mathf.Abs(Vector3Extensions.GetSignedAngleBetween(guideDirection, intersectDirection, Vector3.up)) > 90f) return; intersect.y = TerrainManager.instance.SampleRawHeightSmooth(intersect); var intersectDistance = Mathf.Sqrt(intersectDistanceSqr); var line = new GuideLine(l1, intersect, netInfo.m_halfWidth*2f, intersectDistance, segmentId); int index; if (IsDuplicate(lines, line, out index)) { var d = lines[index]; // If a duplicate, check if it is closer than the duplicate if (Vector3Extensions.DistanceSquared(d.Origin, endPoint) > Vector3Extensions.DistanceSquared(l1, endPoint)) { lines[index] = line; } return; } // Check for intersection with existing nodes var ra = Vector3.Cross(guideDirection, Vector3.up); var quad = new Quad3(l1 + ra, l1 - ra, intersect + ra, intersect - ra); if (NetManager.instance.OverlapQuad(Quad2.XZ(quad), 0, 1280f, netInfo.m_class.m_layer, nodeId, 0, segmentId)) { return; } lines.Add(line); }
private static bool CanNodeBranchInDirection(ushort nodeId, Vector3 direction) { var closestSegmentId = NetNodeUtility.GetClosestSegmentId(nodeId, direction); var exitDirection = NetNodeUtility.GetSegmentExitDirection(nodeId, closestSegmentId); var exitAngle = Vector3Extensions.GetSignedAngleBetween(direction.Flatten(), exitDirection.Flatten(), Vector3.up); return Mathf.Abs(exitAngle) >= 45f; }
static void CalculateAngles(Vector3 anglePosition, Vector3 guideDirection, Vector3 incomingDirection, ICollection<Measurement> measurements) { guideDirection = guideDirection.Flatten().normalized; incomingDirection = incomingDirection.Flatten().normalized; var angleSize = Vector3.Angle(guideDirection, incomingDirection); var angleDirection = Vector3.Normalize(guideDirection + incomingDirection); var otherAngleSize = 180f - angleSize; var otherAngleDirection = Vector3.Normalize(-guideDirection + incomingDirection); if (otherAngleSize < angleSize) { Util.Swap(ref angleSize, ref otherAngleSize); Util.Swap(ref angleDirection, ref otherAngleDirection); } measurements.Add(new AngleMeasurement(angleSize, anglePosition, angleDirection, MeasurementFlags.Primary | MeasurementFlags.Guide)); if (Mathf.Abs(angleSize - 180f) < 0.5f || Mathf.Abs(otherAngleSize - 180f) < 0.5f) return; measurements.Add(new AngleMeasurement(otherAngleSize, anglePosition, otherAngleDirection, MeasurementFlags.Secondary | MeasurementFlags.Guide)); }