public static void Reset() { ClearTemporaryWalls(); tempWallPillarGO = null; tempWallSegmentGO = null; tempWallSegmentBody = null; _startSnapped = false; _endSnapped = false; _isPlacingWall = false; _pillarPrefabs = new List <GameObject>(); _wallPrefabs = new Dictionary <int, GameObject>(); _lastWallLength = 0; }
private void HandleCollision(LSBody other) { if (other.Mover != null) { TouchingObjects.Add(other.Mover); if (IsMoving) { if (!other.Mover.IsMoving && other.Mover.MyMovementGroupID == MyMovementGroupID && other.Mover.StopTime > MinimumOtherStopTime) { StopMove(); } } } }
public static void Reset() { _findingPlacement = false; if (_constructingWall) { _constructingWall = false; WallPositioningHelper.Reset(); } //temp structure no longer required Object.Destroy(tempObject); tempStructure = null; tempStructureBody = null; cachedAgent = null; // remove temporary structure from grid GridBuilder.Reset(); }
public override void Initialize(LSAgent agent) { MyMovementGroupID = -1; Body = agent.Body; Body.Mover = this; Body.OnContact += HandleCollision; Turner = agent.GetAbility <Turn> (); timescaledSpeed = ((Speed * LockstepManager.Timestep) >> FixedMath.SHIFT_AMOUNT); closingDistance = agent.Body.Radius; RepathCount = LSUtility.GetRandom(RepathRate); ViableDestination = false; }
private static bool CheckCircle_Poly(LSBody circle, LSBody poly) { int EdgeCount = poly.EdgeNorms.Length; ClosestDist = long.MaxValue; for (int i = 0; i < EdgeCount; i++) { Vector2d axis = poly.EdgeNorms[i]; long CircleProjection = circle._position.Dot(axis.x, axis.y); long CircleMin = CircleProjection - circle.Radius; long CircleMax = CircleProjection + circle.Radius; long PolyMin; long PolyMax; ProjectPolygon(axis.x, axis.y, poly, out PolyMin, out PolyMax); //TODO: Cache PolyMin and PolyMax? if (CheckOverlap(CircleMin, CircleMax, PolyMin, PolyMax)) { long dist1 = PolyMax - CircleMin; long dist2 = CircleMax - PolyMin; long localCloseDist = 0; if (dist1 <= dist2) { localCloseDist = dist1; } else { localCloseDist = -dist2; } if (localCloseDist.Abs() < ClosestDist.Abs()) { ClosestDist = localCloseDist; ClosestAxis = axis; ClosestAxisProjection = CircleProjection; } } else { return(false); } } return(true); }
public static void CreateStructure(string buildingName, RTSAgent constructingAgent, Rect playingArea) { Vector2d buildPoint = new Vector2d(constructingAgent.transform.position.x, constructingAgent.transform.position.z + 10); RTSAgent buildingTemplate = GameResourceManager.GetAgentTemplate(buildingName); if (buildingTemplate.MyAgentType == AgentType.Building && buildingTemplate.GetComponent <Structure>()) { // check that the Player has the resources available before allowing them to create a new structure if (!_cachedCommander.CachedResourceManager.CheckResources(buildingTemplate)) { Debug.Log("Not enough resources!"); } else { tempObject = Object.Instantiate(buildingTemplate.gameObject, new Vector3(0, 0, 0), Quaternion.identity) as GameObject; if (tempObject) { _findingPlacement = true; SetTransparentMaterial(tempObject, GameResourceManager.AllowedMaterial); tempObject.gameObject.name = buildingName; tempStructure = tempObject.GetComponent <Structure>(); if (tempStructure.StructureType == StructureType.Wall) { // walls require a little help since they are click and drag _constructingWall = true; tempStructure.IsOverlay = true; WallPositioningHelper.Setup(); } tempStructureBody = tempObject.GetComponent <UnityLSBody>().InternalBody; // structure size is 2 times the size of halfwidth & halfheight tempStructure.BuildSizeLow = (tempStructureBody.HalfWidth.CeilToInt() * 2); tempStructure.BuildSizeHigh = (tempStructureBody.HalfLength.CeilToInt() * 2); cachedAgent = constructingAgent; tempStructure.gameObject.transform.position = Positioning.GetSnappedPosition(buildPoint.ToVector3()); } } } }
void DistributeCircle_CirclePriority(LSBody higherPriority, LSBody lowerPriority) { if (true || higherPriority.Immovable || lowerPriority.ImmovableCollisionDirection.EqualsZero()) { DistributeCircle(lowerPriority); lowerPriority.ImmovableCollisionDirection = new Vector2d(DistX, DistY); } else { //TODO: Fix this behavior. It's supposed to prevent pass-through between i.e. buildings. //Only move if there isn't an immovable object in that direction if (lowerPriority.ImmovableCollisionDirection.x.Sign() != DistX.Sign()) { lowerPriority._position.x += DistX; } if (lowerPriority.ImmovableCollisionDirection.y.Sign() != DistY.Sign()) { lowerPriority._position.y += DistY; } } }
public static void ProjectPolygon(long AxisX, long AxisY, LSBody Poly, out long Min, out long Max) { Min = Poly.RealPoints[0].Dot(AxisX, AxisY); Max = Min; int PointCount = Poly.RealPoints.Length; long Projection; for (int i = 1; i < PointCount; i++) { Projection = Poly.RealPoints[i].Dot(AxisX, AxisY); if (Projection < Min) { Min = Projection; } else if (Projection > Max) { Max = Projection; } } }
private void HandleCollision(LSBody other) { if (System.Object.ReferenceEquals(other.Mover, null) == false) { TouchingObjects.Add(other.Mover); if (IsMoving) { if (other.Mover.MyMovementGroupID == MyMovementGroupID) { if (!other.Mover.IsMoving && other.Mover.StopTime > MinimumOtherStopTime) { if (IsFormationMoving) { if (MovementDirection.Dot(TargetDirection.x, TargetDirection.y) < 0) { StopMove(); } } else { StopMove(); } } else if (HasPath && other.Mover.HasPath && other.Mover.PathIndex > 0 && other.Mover.LastTargetPos.SqrDistance(TargetPos.x, TargetPos.y) < FixedMath.One) { if (MovementDirection.Dot(TargetDirection.x, TargetDirection.y) < 0) { PathIndex++; } } } } } }
public override void OnInspectorGUI() { if (Application.isPlaying) { EditorGUILayout.LabelField("Debug Information",EditorStyles.boldLabel); base.DrawDefaultInspector(); return; } EditorGUI.BeginChangeCheck (); if (leTarget == null) { leTarget = (LSBody)target; } if (leTarget.cachedTransform == null) leTarget.cachedTransform = leTarget.GetComponent<Transform>(); if (leTarget.cachedGameObject == null) leTarget.cachedGameObject = leTarget.GetComponent<GameObject>(); Vector3 transformPos = leTarget.cachedTransform.position; leTarget.Position.x = FixedMath.Create (transformPos.x); leTarget.Position.y = FixedMath.Create (transformPos.z); Vector3 transformRot = leTarget.cachedTransform.eulerAngles; leTarget.Rotation = Vector2d.up; leTarget.Rotation.Rotate (FixedMath.Create (Mathf.Sin (transformRot.y * Mathf.Deg2Rad)), FixedMath.Create (Mathf.Cos (transformRot.y * Mathf.Deg2Rad))); //leTarget.Interpolate = EditorGUILayout.Toggle ("Interpolate", leTarget.Interpolate); EditorGUILayout.Space(); EditorGUILayout.LabelField ("Collider Settings",EditorStyles.boldLabel); leTarget.Shape = (ColliderType)EditorGUILayout.EnumPopup("Shape", leTarget.Shape); if (leTarget.Shape == ColliderType.None) return; leTarget.IsTrigger = EditorGUILayout.Toggle ("Is Trigger", leTarget.IsTrigger); if (!leTarget.IsTrigger && !leTarget.Immovable) { GUIContent PriorityContent = new GUIContent ("Priority", "The priority of this object in collisions. Objects of lower priority yield to objects of higher priority."); leTarget.Priority = EditorGUILayout.IntField (PriorityContent, leTarget.Priority); } switch (leTarget.Shape) { case ColliderType.Circle: GUIContent ImmovableContent = new GUIContent ("Immovable", "Is this object immovable, i.e. a wall. Note: non-immovable objects are not supported for any shape except circle."); leTarget.Immovable = EditorGUILayout.Toggle (ImmovableContent, leTarget.Immovable); EditorGUILayout.BeginHorizontal (); LSEditorUtility.FixedNumberField ("Radius", ref leTarget.Radius); EditorGUILayout.EndHorizontal (); break; case ColliderType.AABox: leTarget.Immovable = true; EditorGUILayout.BeginHorizontal (); LSEditorUtility.FixedNumberField ("Half Width", ref leTarget.HalfWidth); EditorGUILayout.EndHorizontal (); EditorGUILayout.BeginHorizontal (); LSEditorUtility.FixedNumberField ("Half Height", ref leTarget.HalfHeight); EditorGUILayout.EndHorizontal (); break; case ColliderType.Polygon: leTarget.Immovable = true; if (leTarget.Vertices == null || leTarget.Vertices.Length == 0) { leTarget.Vertices = new Vector2d[4]; leTarget.Vertices[0] = new Vector2d(FixedMath.Half, FixedMath.Half); leTarget.Vertices[1] = new Vector2d (FixedMath.Half, -FixedMath.Half); leTarget.Vertices[2] = new Vector2d (-FixedMath.Half, -FixedMath.Half); leTarget.Vertices[3] = new Vector2d (-FixedMath.Half, FixedMath.Half); } EditorGUILayout.BeginHorizontal(); int VerticesCount = EditorGUILayout.IntField ("Vertices count", leTarget.Vertices.Length); EditorGUILayout.EndHorizontal(); if (VerticesCount > leTarget.Vertices.Length) { Vector2d[] NewVertices = new Vector2d[VerticesCount]; leTarget.Vertices.CopyTo (NewVertices, 0); for (int i = leTarget.Vertices.Length; i < VerticesCount; i++) { NewVertices[i] = new Vector2d (-FixedMath.One, 0); } leTarget.Vertices = NewVertices; } else if (VerticesCount < leTarget.Vertices.Length) { Vector2d[] NewVertices = new Vector2d[VerticesCount]; for (int i = 0; i < VerticesCount; i++) { NewVertices[i] = leTarget.Vertices[i]; } leTarget.Vertices = NewVertices; } for (int i = 0; i < leTarget.Vertices.Length; i++) { EditorGUILayout.BeginHorizontal(); LSEditorUtility.Vector2dField ("V" + i.ToString () + ":", ref leTarget.Vertices[i]); EditorGUILayout.EndHorizontal(); } break; } SceneView.RepaintAll (); if (EditorGUI.EndChangeCheck()) { Undo.RegisterCompleteObjectUndo (leTarget,"LSBody Change"); EditorUtility.SetDirty (leTarget); } }
public void OnSceneGUI() { if (Application.isPlaying) return; if (leTarget == null) leTarget = (LSBody)(target); Vector3 TargetPosition = leTarget.cachedTransform.position; TargetPosition.y += .55f; Vector3[] PolyLine; switch (leTarget.Shape) { case ColliderType.Circle: Handles.color = FrameColor; Handles.CircleCap (1, TargetPosition, CapRotation, FixedMath.ToFloat (leTarget.Radius)); Handles.CircleCap (1, TargetPosition, CapRotation, FixedMath.ToFloat (leTarget.Radius) + -.005f); Handles.CircleCap (1, TargetPosition, CapRotation, FixedMath.ToFloat (leTarget.Radius) + .005f); Vector3 NewVec = TargetPosition; NewVec.x -= (float)Math.Round(FixedMath.ToDouble (leTarget.Radius), 4, MidpointRounding.AwayFromZero); Handles.color = MoveColor; NewVec = Handles.FreeMoveHandle (NewVec, Quaternion.identity, .35f, Vector3.zero, Handles.SphereCap); leTarget.Radius = FixedMath.Create (NewVec.x - TargetPosition.x); if (leTarget.Radius < 0) leTarget.Radius = -leTarget.Radius; break; case ColliderType.AABox: float halfWidth = FixedMath.ToFloat(leTarget.HalfWidth); float halfHeight = FixedMath.ToFloat (leTarget.HalfHeight); PolyLine = new Vector3[5]; for (int i = 0; i < 4; i++) { PolyLine[i] = TargetPosition; } PolyLine[0].x += halfWidth; PolyLine[0].z += halfHeight; PolyLine[1].x += halfWidth; PolyLine[1].z -= halfHeight; PolyLine[2].x -= halfWidth; PolyLine[2].z -= halfHeight; PolyLine[3].x -= halfWidth; PolyLine[3].z += halfHeight; PolyLine[4] = PolyLine[0]; Handles.color = FrameColor; Handles.DrawAAPolyLine (5f,PolyLine); Handles.color = MoveColor; Vector3 WidthScaler = TargetPosition; WidthScaler.x -= (float)LSEditorUtility.Round (leTarget.HalfWidth); WidthScaler = Handles.FreeMoveHandle (WidthScaler, Quaternion.identity, .35f, Vector3.zero, Handles.SphereCap); leTarget.HalfWidth = FixedMath.Create (WidthScaler.x - TargetPosition.x); Vector3 HeightScaler = TargetPosition; HeightScaler.z -= (float)LSEditorUtility.Round (leTarget.HalfHeight); HeightScaler = Handles.FreeMoveHandle (HeightScaler, Quaternion.identity, .35f, Vector3.zero, Handles.SphereCap); leTarget.HalfHeight = FixedMath.Create (HeightScaler.z - TargetPosition.z); if (leTarget.HalfWidth <= 0) leTarget.HalfWidth = -leTarget.HalfWidth; if (leTarget.HalfHeight < 0) leTarget.HalfHeight = -leTarget.HalfHeight; break; case ColliderType.Polygon: if (leTarget.Vertices == null || leTarget.Vertices.Length == 0) break; PolyLine = new Vector3[leTarget.Vertices.Length + 1]; Handles.color = MoveColor; for (int i = 0; i < leTarget.Vertices.Length; i++) { Vector3 vertPos = leTarget.Vertices[i].ToVector3(0f) + TargetPosition; Vector3 freemoveVec = Handles.FreeMoveHandle (vertPos, Quaternion.identity, .35f, Vector3.zero, Handles.SphereCap) - TargetPosition; leTarget.Vertices[i] = new Vector2d (FixedMath.Create (freemoveVec.x), FixedMath.Create(freemoveVec.z)); Handles.Label (vertPos, "V" + i.ToString()); PolyLine[i] = vertPos; } PolyLine[leTarget.Vertices.Length] = PolyLine[0]; Handles.color = FrameColor; Handles.DrawAAPolyLine (5f,PolyLine); break; } }
void OnSceneGUI() { if (MoreThanOne) { return; } //Have to reinitialize everything because can't apply modified properties on base.serializedObject SerializedObject so = new SerializedObject(target); so.Update(); SerializedProperty Shape = so.FindProperty("_internalBody").FindPropertyRelative("_shape"); SerializedProperty HalfWidth = so.FindProperty("_internalBody").FindPropertyRelative("_halfWidth"); SerializedProperty HalfHeight = so.FindProperty("_internalBody").FindPropertyRelative("_halfHeight"); SerializedProperty Radius = so.FindProperty("_internalBody").FindPropertyRelative("_radius"); SerializedProperty Height = so.FindProperty("_internalBody").FindPropertyRelative("_height"); /* * //Currently unused * SerializedProperty Layer = so.FindProperty("_internalBody").FindPropertyRelative("_layer"); * SerializedProperty IsTrigger = so.FindProperty("_internalBody").FindPropertyRelative("_isTrigger"); * SerializedProperty Immovable = so.FindProperty("_internalBody").FindPropertyRelative("_immovable"); * SerializedProperty Vertices = so.FindProperty("_internalBody").FindPropertyRelative("_vertices"); * SerializedProperty PositionalTransform = so.FindProperty("_internalBody").FindPropertyRelative("_positionalTransform"); * SerializedProperty RotationalTransform = so.FindProperty("_internalBody").FindPropertyRelative("_rotationalTransform"); */ ColliderType shape = (ColliderType)Shape.intValue; if (shape == ColliderType.None) { return; } Handles.color = Color.blue; LSBody Body = ((UnityLSBody)target).InternalBody; Transform transform = ((UnityLSBody)target).transform; Vector3 targetPos = transform.position; const int ImprecisionLimit = 100000; if (Mathf.Abs(targetPos.x) >= ImprecisionLimit || Mathf.Abs(targetPos.y) >= ImprecisionLimit || Mathf.Abs(targetPos.z) >= ImprecisionLimit) { return; } const float spread = .02f; int spreadMin = -1; int spreadMax = 1; Handles.DrawCapFunction dragCap = Handles.SphereCap; float height = targetPos.y; float xModifier = 0f; if (shape == ColliderType.Circle) { //Minus so the move handle doesn't end up on the same axis as the transform.position move handle float oldRadius = Radius.longValue.ToFloat(); float newRadius = Mathf.Abs( (Handles.FreeMoveHandle( new Vector3(targetPos.x - Radius.longValue.ToFloat(), targetPos.y, targetPos.z) , Quaternion.identity, MoveHandleSize, Vector3.zero, Handles.SphereCap)) .x - targetPos.x); if (Mathf.Abs(oldRadius - newRadius) >= .02f) { Radius.longValue = FixedMath.Create(newRadius); } Handles.DrawLine(targetPos, new Vector3(targetPos.x + Radius.longValue.ToFloat(), targetPos.y, targetPos.z)); float baseHeight = targetPos.y; for (int i = spreadMin; i <= spreadMax; i++) { Handles.CircleCap( 1, new Vector3(targetPos.x, baseHeight + (float)i * spread, targetPos.z) , Quaternion.Euler(90, 0, 0), Radius.longValue.ToFloat()); } baseHeight = targetPos.y + Height.longValue.ToFloat(); for (int i = spreadMin; i <= spreadMax; i++) { Handles.CircleCap( 1, new Vector3(targetPos.x, baseHeight + (float)i * spread, targetPos.z) , Quaternion.Euler(90, 0, 0), Radius.longValue.ToFloat()); } xModifier = 0;//Radius.longValue.ToFloat(); } else if (shape == ColliderType.AABox) { float oldWidth = HalfWidth.longValue.ToFloat(); float newWidth = Mathf.Abs( Handles.FreeMoveHandle( new Vector3(targetPos.x - (float)HalfWidth.longValue.ToFormattedDouble(), targetPos.y, targetPos.z), Quaternion.identity, MoveHandleSize, Vector3.zero, dragCap) .x - targetPos.x); if (Mathf.Abs(newWidth - oldWidth) >= .02f) { HalfWidth.longValue = FixedMath.Create(newWidth); } float oldHeight = HalfHeight.longValue.ToFloat(); float newHeight = System.Math.Abs( Handles.FreeMoveHandle( new Vector3(targetPos.x, targetPos.y, targetPos.z - (float)HalfHeight.longValue.ToFormattedDouble()), Quaternion.identity, MoveHandleSize, Vector3.zero, dragCap) .z - targetPos.z); if (Mathf.Abs(newHeight - oldHeight) >= .02f) { HalfHeight.longValue = FixedMath.Create(newHeight); } float halfWidth = HalfWidth.longValue.ToFloat(); float halfHeight = HalfHeight.longValue.ToFloat(); for (int i = 0; i < 1; i++) { height = targetPos.y + (float)i * spread; Vector3[] lines = new Vector3[] { new Vector3(targetPos.x + halfWidth, height, targetPos.z + halfHeight), new Vector3(targetPos.x + halfWidth, height, targetPos.z - halfHeight), new Vector3(targetPos.x + halfWidth, height, targetPos.z - halfHeight), new Vector3(targetPos.x - halfWidth, height, targetPos.z - halfHeight), new Vector3(targetPos.x - halfWidth, height, targetPos.z - halfHeight), new Vector3(targetPos.x - halfWidth, height, targetPos.z + halfHeight), new Vector3(targetPos.x - halfWidth, height, targetPos.z + halfHeight), new Vector3(targetPos.x + halfWidth, height, targetPos.z + halfHeight) }; Handles.DrawPolyLine(lines); } for (int i = 0; i < 1; i++) { height = targetPos.y + (float)i * spread + Height.longValue.ToFloat(); Vector3[] lines = new Vector3[] { new Vector3(targetPos.x + halfWidth, height, targetPos.z + halfHeight), new Vector3(targetPos.x + halfWidth, height, targetPos.z - halfHeight), new Vector3(targetPos.x + halfWidth, height, targetPos.z - halfHeight), new Vector3(targetPos.x - halfWidth, height, targetPos.z - halfHeight), new Vector3(targetPos.x - halfWidth, height, targetPos.z - halfHeight), new Vector3(targetPos.x - halfWidth, height, targetPos.z + halfHeight), new Vector3(targetPos.x - halfWidth, height, targetPos.z + halfHeight), new Vector3(targetPos.x + halfWidth, height, targetPos.z + halfHeight) }; Handles.DrawPolyLine(lines); } xModifier = 0;//halfWidth; } else if (shape == ColliderType.Polygon) { float yRot = transform.eulerAngles.y * Mathf.Deg2Rad; Vector2d rotation = Vector2d.CreateRotation(yRot); bool changed = false; Vector3[] draws = new Vector3[Body.Vertices.Length + 1]; for (int i = 0; i < Body.Vertices.Length; i++) { Vector2d vertex = Body.Vertices [i]; vertex.Rotate(rotation.x, rotation.y); Vector3 drawPos = vertex.ToVector3() + targetPos; Vector3 newDrawPos = Handles.FreeMoveHandle(drawPos, Quaternion.identity, MoveHandleSize, new Vector3(0, float.PositiveInfinity, 0), Handles.SphereCap); if ((newDrawPos - (drawPos)).magnitude >= .01f) { newDrawPos -= targetPos; vertex = new Vector2d(newDrawPos); vertex.RotateInverse(rotation.x, rotation.y); Body.Vertices [i] = vertex; changed = true; } draws[i] = drawPos; Handles.Label(drawPos, "V: " + i.ToString(), LabelStyle); } if (Body.Vertices.Length > 0) { draws[draws.Length - 1] = draws[0]; Handles.DrawPolyLine(draws); for (int i = 0; i < draws.Length; i++) { Vector3 highPos = draws[i]; highPos.y += Body.Height.ToFloat(); Handles.DrawLine(draws[i], highPos); draws[i] = highPos; } Handles.DrawPolyLine(draws); } if (changed) { so.Update(); } } Handles.DrawLine( new Vector3(targetPos.x + xModifier, targetPos.y, targetPos.z), new Vector3(targetPos.x + xModifier, targetPos.y + Height.longValue.ToFloat(), targetPos.z)); Vector3 movePos = targetPos; movePos.x += xModifier; movePos.y += (float)Height.longValue.ToFormattedDouble(); Vector3 lastMovePos = movePos; movePos = Handles.FreeMoveHandle( movePos, Quaternion.identity, MoveHandleSize, Vector3.zero, dragCap ); if ((lastMovePos - movePos).sqrMagnitude >= .1f) { Height.longValue = FixedMath.Create(Mathf.Max(Mathf.Abs(movePos.y - targetPos.y))); } so.ApplyModifiedProperties(); }
public static bool CheckCircle_Box(LSBody box, LSBody circle) { Collided = false; xMore = circle._position.x > box._position.x; yMore = circle._position.y > box._position.y; if (!Collided) { Collided = false; if (xMore) { if (circle._position.x <= box.XMax) { Collided = true; } } else { if (circle._position.x >= box.XMin) { Collided = true; } } if (yMore) { if (circle._position.y <= box.YMax) { Collided = true; } } else { if (circle._position.y >= box.YMin) { Collided = true; } } if (!Collided) { if (xMore) { xDist = (circle._position.x) - (box.XMax); } else { xDist = (circle._position.x) - (box.XMin); } if (yMore) { yDist = (circle._position.y) - (box.YMax); } else { yDist = (circle._position.y) - (box.YMin); } if ((xDist * xDist + yDist * yDist) <= circle.Radius * circle.Radius) { Collided = true; } } } return(Collided); }
private void DistributeCircle_Box(LSBody box, LSBody circle) { xMore = circle._position.x > box._position.x; yMore = circle._position.y > box._position.y; if (xMore) { PenetrationX = (circle.XMin - box.XMax); } else { PenetrationX = (circle.XMax - box.XMin); } if (yMore) { PenetrationY = (circle.YMin - box.YMax); } else { PenetrationY = (circle.YMax - box.YMin); } //PenetrationX = PenetrationX + circle.Velocity.x; //PenetrationY = PenetrationY + circle.Velocity.y; xAbs = PenetrationX < 0 ? -PenetrationX : PenetrationX; yAbs = PenetrationY < 0 ? -PenetrationY : PenetrationY; if ((xAbs <= circle.Radius && yAbs <= circle.Radius)) { Vector2d corner; corner.x = xMore ? box.Position.x + box.HalfWidth : box.Position.x - box.HalfWidth; corner.y = yMore ? box.Position.y + box.HalfHeight : box.Position.y - box.HalfHeight; Vector2d dir = circle.Position - corner; dir.Normalize(); circle.Position = corner + dir * circle.Radius; } else { if (xAbs > yAbs) { PenetrationX = 0; //if (yAbs < circle.Radius) PenetrationY = PenetrationY * yAbs / circle.Radius; if (PenetrationY > 0 == yMore) { PenetrationY = -PenetrationY; } } else { PenetrationY = 0; //if (xAbs < circle.Radius) PenetrationX = PenetrationX * xAbs / circle.Radius; if (PenetrationX > 0 == xMore) { PenetrationX = -PenetrationX; } } //Resolving circle._position.x -= PenetrationX; circle._position.y -= PenetrationY; } circle.PositionChanged = true; circle.BuildBounds(); }
public void Initialize(LSBody b1, LSBody b2) { IsValid = true; if (!IsValid) { return; } if (b1.ID < b2.ID) { Body1 = b1; Body2 = b2; } else { Body1 = b2; Body2 = b1; } _ranIndex = -1; _isColliding = false; DistX = 0; DistY = 0; PenetrationX = 0; PenetrationY = 0; FastCollideDistance = b1.Radius + b2.Radius; FastCollideDistance *= FastCollideDistance; LeCollisionType = CollisionType.None; if (Body1.Shape == ColliderType.None || Body2.Shape == ColliderType.None) { } else if (Body1.Shape == ColliderType.Circle) { if (Body2.Shape == ColliderType.Circle) { LeCollisionType = CollisionType.Circle_Circle; } else if (Body2.Shape == ColliderType.AABox) { LeCollisionType = CollisionType.Circle_AABox; } else if (Body2.Shape == ColliderType.Polygon) { LeCollisionType = CollisionType.Circle_Polygon; } } else if (Body1.Shape == ColliderType.AABox) { if (Body2.Shape == ColliderType.Circle) { LeCollisionType = CollisionType.Circle_AABox; } else if (Body2.Shape == ColliderType.AABox) { LeCollisionType = CollisionType.AABox_AABox; } else if (Body2.Shape == ColliderType.Polygon) { LeCollisionType = CollisionType.AABox_Polygon; } } else if (Body1.Shape == ColliderType.Polygon) { if (Body2.Shape == ColliderType.Circle) { LeCollisionType = CollisionType.Circle_Polygon; } else if (Body2.Shape == ColliderType.AABox) { LeCollisionType = CollisionType.AABox_Polygon; } else if (Body2.Shape == ColliderType.Polygon) { LeCollisionType = CollisionType.Polygon_Polygon; } } DoPhysics = ((Body1.IsTrigger || Body2.IsTrigger) == false); if (DoPhysics) { } //TODO: Space out checks when culled //TODO: The time between collision checks might cause goofy behavior //Maybe use a distance or velocity heuristic for culling instead of time since last collision //It wouldn't be able to replace partitions because of raycasts and fast-moving objects //Let's see if this works well or if something better is needed. if (Body1.PreventCulling || Body2.PreventCulling) { //Never cull CullCounter = -1; } else { //Immediately check collision CullCounter = 0; //If collision distance is too large, don't cull based on distance PreventDistanceCull = FastCollideDistance > PhysicsManager.CullFastDistanceMax; LastCollidedFrame = LockstepManager.FrameCount; FastDistanceOffset = FixedMath.Sqrt(FastCollideDistance >> FixedMath.SHIFT_AMOUNT) + FixedMath.One * 2; FastDistanceOffset *= FastDistanceOffset; } Active = true; _Version++; }
public override void OnInspectorGUI() { if (Application.isPlaying) { EditorGUILayout.LabelField("Debug Information", EditorStyles.boldLabel); base.DrawDefaultInspector(); return; } EditorGUI.BeginChangeCheck(); LSBody[] Bodies = GenerateTargets(); LSBody Body = Bodies[0]; if (Bodies.Length == 1) { Body._positionalTransform = (Transform)EditorGUILayout.ObjectField( "Positional Transform", Body._positionalTransform, typeof(Transform), true); Body._rotationalTransform = (Transform)EditorGUILayout.ObjectField( "Rotational Transform", Body._rotationalTransform, typeof(Transform), true); EditorGUILayout.Space(); } Body.Layer = EditorGUILayout.LayerField("Layer", Body.Layer); for (int i = 0; i < Bodies.Length; i++) { LSBody body = Bodies[i]; Transform posTransform = body._positionalTransform != null ? body._positionalTransform : body.transform; body.Position = new Vector2d(posTransform.position); Transform rotTransform = body._rotationalTransform != null ? body._rotationalTransform : body.transform; body.Rotation = new Vector2d(Mathf.Sin(rotTransform.rotation.x), Mathf.Cos(rotTransform.rotation.y)); } EditorGUILayout.LabelField("Collider Settings", EditorStyles.boldLabel); Body.Shape = (ColliderType)EditorGUILayout.EnumPopup("Shape", Body.Shape); for (int i = 1; i < Bodies.Length; i++) { Bodies[i].Shape = Body.Shape; } if (Body.Shape == ColliderType.None) { return; } Body.IsTrigger = EditorGUILayout.Toggle("Is Trigger", Body.IsTrigger); if (!Body.IsTrigger && !Body.Immovable) { var PriorityContent = new GUIContent("Priority", "The priority of this object in collisions. Objects of lower priority yield to objects of higher priority."); SerializedProperty sp = serializedObject.FindProperty("_priority"); sp.intValue = EditorGUILayout.IntField(PriorityContent, sp.intValue); } switch (Body.Shape) { case ColliderType.Circle: var ImmovableContent = new GUIContent("Immovable", "Is this object immovable, i.e. a wall. Note: non-immovable objects are not supported for any shape except circle."); Body.Immovable = EditorGUILayout.Toggle(ImmovableContent, Body.Immovable); LSEditorUtility.FixedNumberField("Radius", ref Body.Radius); for (int i = 1; i < Bodies.Length; i++) { Bodies[i].Radius = Body.Radius; } break; case ColliderType.AABox: LSEditorUtility.FixedNumberField("Half Width", ref Body.HalfWidth); LSEditorUtility.FixedNumberField("Half Height", ref Body.HalfHeight); for (int i = 1; i < Bodies.Length; i++) { Bodies[i].HalfWidth = Body.HalfWidth; Bodies[i].HalfHeight = Body.HalfHeight; } break; case ColliderType.Polygon: if (Body.Vertices == null || Body.Vertices.Length == 0) { Body.Vertices = new Vector2d[4]; Body.Vertices [0] = new Vector2d(FixedMath.Half, FixedMath.Half); Body.Vertices [1] = new Vector2d(FixedMath.Half, -FixedMath.Half); Body.Vertices [2] = new Vector2d(-FixedMath.Half, -FixedMath.Half); Body.Vertices [3] = new Vector2d(-FixedMath.Half, FixedMath.Half); } int VerticesCount = EditorGUILayout.IntField("Vertices count", Body.Vertices.Length); if (VerticesCount > Body.Vertices.Length) { var NewVertices = new Vector2d[VerticesCount]; Body.Vertices.CopyTo(NewVertices, 0); for (int i = Body.Vertices.Length; i < VerticesCount; i++) { NewVertices [i] = new Vector2d(-FixedMath.One, 0); } Body.Vertices = NewVertices; } else if (VerticesCount < Body.Vertices.Length) { var NewVertices = new Vector2d[VerticesCount]; for (int i = 0; i < VerticesCount; i++) { NewVertices [i] = Body.Vertices [i]; } Body.Vertices = NewVertices; } for (int i = 0; i < Body.Vertices.Length; i++) { LSEditorUtility.Vector2dField("V" + i.ToString() + ":", ref Body.Vertices [i]); } for (int i = 1; i < Bodies.Length; i++) { Bodies[i].Vertices = Body.Vertices; } break; } for (int i = 1; i < Bodies.Length; i++) { Bodies[i].IsTrigger = Body.IsTrigger; Bodies[i].Immovable = Body.Immovable; Bodies[i].IsTrigger = Body.IsTrigger; } if (EditorGUI.EndChangeCheck()) { Undo.RegisterCompleteObjectUndo(Body, "LSBody Change"); serializedObject.ApplyModifiedProperties(); SceneView.RepaintAll(); } }
public override void OnInspectorGUI() { if (Application.isPlaying) { EditorGUILayout.LabelField("Debug Information", EditorStyles.boldLabel); base.DrawDefaultInspector(); return; } EditorGUI.BeginChangeCheck(); if (leTarget == null) { leTarget = (LSBody)target; } if (leTarget.cachedTransform == null) { leTarget.cachedTransform = leTarget.GetComponent <Transform>(); } if (leTarget.cachedGameObject == null) { leTarget.cachedGameObject = leTarget.GetComponent <GameObject>(); } Vector3 transformPos = leTarget.cachedTransform.position; leTarget.Position.x = FixedMath.Create(transformPos.x); leTarget.Position.y = FixedMath.Create(transformPos.z); Vector3 transformRot = leTarget.cachedTransform.eulerAngles; leTarget.Rotation = Vector2d.up; leTarget.Rotation.Rotate(FixedMath.Create(Mathf.Sin(transformRot.y * Mathf.Deg2Rad)), FixedMath.Create(Mathf.Cos(transformRot.y * Mathf.Deg2Rad))); //leTarget.Interpolate = EditorGUILayout.Toggle ("Interpolate", leTarget.Interpolate); EditorGUILayout.Space(); EditorGUILayout.LabelField("Collider Settings", EditorStyles.boldLabel); leTarget.Shape = (ColliderType)EditorGUILayout.EnumPopup("Shape", leTarget.Shape); if (leTarget.Shape == ColliderType.None) { return; } leTarget.IsTrigger = EditorGUILayout.Toggle("Is Trigger", leTarget.IsTrigger); if (!leTarget.IsTrigger) { GUIContent PriorityContent = new GUIContent("Priority", "The priority of this object in collisions. Objects of lower priority yield to objects of higher priority."); //leTarget.Priority = EditorGUILayout.IntField (PriorityContent, leTarget.Priority); } EditorGUILayout.Space(); switch (leTarget.Shape) { case ColliderType.Circle: GUIContent ImmovableContent = new GUIContent("Immovable", "Is this object immovable, i.e. a wall. Note: non-immovable objects are not supported for any shape except circle."); leTarget.Immovable = EditorGUILayout.Toggle(ImmovableContent, leTarget.Immovable); EditorGUILayout.BeginHorizontal(); LSEditorUtility.FixedNumberField("Radius", ref leTarget.Radius); EditorGUILayout.EndHorizontal(); break; case ColliderType.AABox: leTarget.Immovable = true; EditorGUILayout.BeginHorizontal(); LSEditorUtility.FixedNumberField("Half Width", ref leTarget.HalfWidth); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); LSEditorUtility.FixedNumberField("Half Height", ref leTarget.HalfHeight); EditorGUILayout.EndHorizontal(); break; case ColliderType.Polygon: leTarget.Immovable = true; if (leTarget.Vertices == null || leTarget.Vertices.Length == 0) { leTarget.Vertices = new Vector2d[4]; leTarget.Vertices[0] = new Vector2d(FixedMath.Half, FixedMath.Half); leTarget.Vertices[1] = new Vector2d(FixedMath.Half, -FixedMath.Half); leTarget.Vertices[2] = new Vector2d(-FixedMath.Half, -FixedMath.Half); leTarget.Vertices[3] = new Vector2d(-FixedMath.Half, FixedMath.Half); } EditorGUILayout.BeginHorizontal(); int VerticesCount = EditorGUILayout.IntField("Vertices count", leTarget.Vertices.Length); EditorGUILayout.EndHorizontal(); if (VerticesCount > leTarget.Vertices.Length) { Vector2d[] NewVertices = new Vector2d[VerticesCount]; leTarget.Vertices.CopyTo(NewVertices, 0); for (int i = leTarget.Vertices.Length; i < VerticesCount; i++) { NewVertices[i] = new Vector2d(-FixedMath.One, 0); } leTarget.Vertices = NewVertices; } else if (VerticesCount < leTarget.Vertices.Length) { Vector2d[] NewVertices = new Vector2d[VerticesCount]; for (int i = 0; i < VerticesCount; i++) { NewVertices[i] = leTarget.Vertices[i]; } leTarget.Vertices = NewVertices; } for (int i = 0; i < leTarget.Vertices.Length; i++) { EditorGUILayout.BeginHorizontal(); LSEditorUtility.Vector2dField("V" + i.ToString() + ":", ref leTarget.Vertices[i]); EditorGUILayout.EndHorizontal(); } break; } SceneView.RepaintAll(); if (EditorGUI.EndChangeCheck()) { Undo.RegisterCompleteObjectUndo(leTarget, "LSBody Change"); EditorUtility.SetDirty(leTarget); } }
public void OnSceneGUI() { if (Application.isPlaying) { return; } if (leTarget == null) { leTarget = (LSBody)(target); } Vector3 TargetPosition = leTarget.cachedTransform.position; TargetPosition.y += .55f; Vector3[] PolyLine; switch (leTarget.Shape) { case ColliderType.Circle: Handles.color = FrameColor; Handles.CircleCap(1, TargetPosition, CapRotation, FixedMath.ToFloat(leTarget.Radius)); Handles.CircleCap(1, TargetPosition, CapRotation, FixedMath.ToFloat(leTarget.Radius) + -.005f); Handles.CircleCap(1, TargetPosition, CapRotation, FixedMath.ToFloat(leTarget.Radius) + .005f); Vector3 NewVec = TargetPosition; NewVec.x -= (float)Math.Round(FixedMath.ToDouble(leTarget.Radius), 4, MidpointRounding.AwayFromZero); Handles.color = MoveColor; NewVec = Handles.FreeMoveHandle(NewVec, Quaternion.identity, .35f, Vector3.zero, Handles.SphereCap); leTarget.Radius = FixedMath.Create(NewVec.x - TargetPosition.x); if (leTarget.Radius < 0) { leTarget.Radius = -leTarget.Radius; } break; case ColliderType.AABox: float halfWidth = FixedMath.ToFloat(leTarget.HalfWidth); float halfHeight = FixedMath.ToFloat(leTarget.HalfHeight); PolyLine = new Vector3[5]; for (int i = 0; i < 4; i++) { PolyLine[i] = TargetPosition; } PolyLine[0].x += halfWidth; PolyLine[0].z += halfHeight; PolyLine[1].x += halfWidth; PolyLine[1].z -= halfHeight; PolyLine[2].x -= halfWidth; PolyLine[2].z -= halfHeight; PolyLine[3].x -= halfWidth; PolyLine[3].z += halfHeight; PolyLine[4] = PolyLine[0]; Handles.color = FrameColor; Handles.DrawAAPolyLine(5f, PolyLine); Handles.color = MoveColor; Vector3 WidthScaler = TargetPosition; WidthScaler.x -= (float)LSEditorUtility.Round(leTarget.HalfWidth); WidthScaler = Handles.FreeMoveHandle(WidthScaler, Quaternion.identity, .35f, Vector3.zero, Handles.SphereCap); leTarget.HalfWidth = FixedMath.Create(WidthScaler.x - TargetPosition.x); Vector3 HeightScaler = TargetPosition; HeightScaler.z -= (float)LSEditorUtility.Round(leTarget.HalfHeight); HeightScaler = Handles.FreeMoveHandle(HeightScaler, Quaternion.identity, .35f, Vector3.zero, Handles.SphereCap); leTarget.HalfHeight = FixedMath.Create(HeightScaler.z - TargetPosition.z); if (leTarget.HalfWidth <= 0) { leTarget.HalfWidth = -leTarget.HalfWidth; } if (leTarget.HalfHeight < 0) { leTarget.HalfHeight = -leTarget.HalfHeight; } break; case ColliderType.Polygon: if (leTarget.Vertices == null || leTarget.Vertices.Length == 0) { break; } PolyLine = new Vector3[leTarget.Vertices.Length + 1]; Handles.color = MoveColor; for (int i = 0; i < leTarget.Vertices.Length; i++) { Vector3 vertPos = leTarget.Vertices[i].ToVector3(0f) + TargetPosition; Vector3 freemoveVec = Handles.FreeMoveHandle(vertPos, Quaternion.identity, .35f, Vector3.zero, Handles.SphereCap) - TargetPosition; leTarget.Vertices[i] = new Vector2d(FixedMath.Create(freemoveVec.x), FixedMath.Create(freemoveVec.z)); Handles.Label(vertPos, "V" + i.ToString()); PolyLine[i] = vertPos; } PolyLine[leTarget.Vertices.Length] = PolyLine[0]; Handles.color = FrameColor; Handles.DrawAAPolyLine(5f, PolyLine); break; } }