public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { // cache this so we can reset it at the end bool showMixedValue = EditorGUI.showMixedValue; if (property.hasMultipleDifferentValues) { // show a dash instead of numbers in the FloatField EditorGUI.showMixedValue = true; } // start observing GUI to see if user does something EditorGUI.BeginChangeCheck(); var value = FixedMath.Create(EditorGUI.FloatField(position, label, property.longValue.ToFloat())); // if the user messed with the FloatField if (EditorGUI.EndChangeCheck()) { // set the propery (including multi-value) to the new value property.longValue = value; } // draw the long value in the bottom right corner GUI.Label(position, new GUIContent(property.longValue.ToString()), style); // reset the showMixedValue flag (maybe not necessary) EditorGUI.showMixedValue = showMixedValue; }
public static FixedAnimationClip CreateFixedAnimationClip(AnimationClip clip) { FixedAnimationClip fixedAnimationClip = new FixedAnimationClip(); //fixedAnimationClip.Transform = transform; fixedAnimationClip.Length = FixedMath.Create(clip.length); var clips = UnityEditor.AnimationUtility.GetCurveBindings(clip); for (int i = 0; i < clips.Length; i++) { var c = clips[i]; var ocurve = UnityEditor.AnimationUtility.GetEditorCurve(clip, c); var fcurve = FixedAnimationCurve.CreateFixedAnimationCurve(ocurve); if (c.propertyName.Equals("m_LocalPosition.x")) { fixedAnimationClip.LocalPositionX = fcurve; } else if (c.propertyName.Equals("m_LocalPosition.y")) { fixedAnimationClip.LocalPositionY = fcurve; } else if (c.propertyName.Equals("m_LocalPosition.z")) { fixedAnimationClip.LocalPositionZ = fcurve; } } return(fixedAnimationClip); }
//TODO 非常粗略的判断 private bool Sector_Rectangle(Body sector, Body rectangle) { if (rectangle.position.FastDistance(sector.position) > (rectangle.width + sector.radius) * (rectangle.length + sector.radius)) { return(false); } Vector2d dir = (rectangle.position - sector.position); dir.Normalize(); sector.direction.Normalize(); long angle = sector.direction.GetRotationAngle(dir); //Debug.Log("angle " + angle.ToFloat() + " sector.angle/2 -> " + sector.angle.Mul(FixedMath.Half).ToFloat() + " (360 - sector.angle / 2) " + (FixedMath.Create(360) - sector.angle.Mul(FixedMath.Half)).ToFloat()); if (angle < sector.angle.Mul(FixedMath.Half) || angle > FixedMath.Create(360) - sector.angle.Mul(FixedMath.Half) ) { return(true); } else { return(false); } }
protected override void OnEnter(AIAgent agent) { base.OnStart(agent); _onRightPlace = false; target = agent.Blackboard.GetItem("Target") as SceneObject; if (target != null) { var speed = SceneObject.AttributeManager[AttributeType.MaxSpeed]; SceneObject.AttributeManager.SetBase(AttributeType.Speed, speed); target.TransformComp.EventGroup.ListenEvent((int)TransformComponent.Event.OnPositionChange, OnTargetPosiChanged); } if (Vector3d.SqrDistance(target.Position, agent.SceneObject.Position) < FixedMath.Create(300 / 100) * (300 / 100)) { _onRightPlace = true; } else { _onRightPlace = OnRightPlace(); if (!_onRightPlace) { //_pathFollowSteering = _npc.SteeringManager.AddSteering<PathFollowSteering>(2); CacualtePath(); } } }
private bool Circle_Sector(Body circle, Body sector) { Vector2d forword = sector.direction; //Debug.Log("distance " + circle.position.FastDistance(sector.position).ToFloat()); if (circle.position.FastDistance(sector.position) > (circle.radius + sector.radius) * (circle.radius + sector.radius)) { return(false); } Vector2d dir = (circle.position - sector.position); dir.Normalize(); sector.direction.Normalize(); long angle = sector.direction.GetRotationAngle(dir); //Debug.Log("angle " + angle.ToFloat() + " sector.angle/2 -> " + sector.angle.Mul(FixedMath.Half).ToFloat() + " (360 - sector.angle / 2) " + (FixedMath.Create(360) - sector.angle.Mul(FixedMath.Half)).ToFloat()); if (angle < sector.angle.Mul(FixedMath.Half) || angle > FixedMath.Create(360) - sector.angle.Mul(FixedMath.Half) ) { return(true); } else { return(false); } }
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { VectorRotationAttribute at = this.attribute as VectorRotationAttribute; bool timescaled = at.Timescaled; double scale = LSEditorUtility.Scale(timescaled); SerializedProperty x = property.FindPropertyRelative("x"); SerializedProperty y = property.FindPropertyRelative("y"); double angleInRadians = Math.Atan2(y.longValue.ToDouble(), x.longValue.ToDouble()); double angleInDegrees = (angleInRadians * 180d / Math.PI) * scale; height = 15f; position.height = height; angleInDegrees = (EditorGUI.DoubleField(position, "Angle", angleInDegrees)) / scale; double newAngleInRadians = angleInDegrees * Math.PI / 180d; if (Math.Abs(newAngleInRadians - angleInRadians) >= .001f) { long cos = FixedMath.Create(Math.Cos(newAngleInRadians)); long sin = FixedMath.Create(Math.Sin(newAngleInRadians)); x.longValue = cos; y.longValue = sin; } }
/// <summary> /// Finds closest next-best-node also when destination is off invalid /// </summary> /// <param name="from"></param> /// <param name="dest"></param> /// <param name="returnNode"></param> /// <returns></returns> public static bool GetEndNode(Vector2d from, Vector2d dest, out GridNode outputNode) { outputNode = GridManager.GetNode(dest.x, dest.y); if (outputNode == null) { //If null, it is off the grid. Raycast back onto grid for closest viable node to the destination. foreach (var coordinate in PanLineAlgorithm.FractionalLineAlgorithm.Trace( dest.x.ToDouble(), dest.y.ToDouble(), from.x.ToDouble(), from.y.ToDouble())) { outputNode = GridManager.GetNode( FixedMath.Create(coordinate.X), FixedMath.Create(coordinate.Y)); if (outputNode != null) { return(true); } } return(false); } else if (outputNode.Unwalkable) { if (AllowUnwalkableEndNode && AlternativeNodeFinder.Instance.CheckValidNeighbor(outputNode)) { return(true); } return(StarCast(dest, out outputNode)); } return(true); }
public override void Execute(SceneObject sender, SceneObject reciever, object data) { if (reciever != null) { reciever.Hp += FixedMath.Create(Hp.value); } base.Execute(sender, reciever, data); }
public void ValueRollbackTest() { ResourcesConfigManager.Initialize(); WorldManager.IntervalTime = 100; LockStepEntityTestWorld world = (LockStepEntityTestWorld)WorldManager.CreateWorld <LockStepEntityTestWorld>(); world.IsClient = true; world.IsStart = true; world.IsLocal = true; ConnectStatusComponent csc = world.GetSingletonComp <ConnectStatusComponent>(); csc.confirmFrame = 0; //从目标帧之后开始计算 SelfComponent sc = new SelfComponent(); RealPlayerComponent rp = new RealPlayerComponent(); EntityBase c1 = world.CreateEntityImmediately("Test", sc, rp); LockStepInputSystem.commandCache.moveDir.x = FixedMath.Create(1000); world.CallRecalc(); world.FixedLoop(WorldManager.IntervalTime); LockStepInputSystem.commandCache.moveDir.x = FixedMath.Create(0000); MoveComponent mc = c1.GetComp <MoveComponent>(); //Debug.Log("mc.pos.x " + mc.pos.x + " frame " + world.FrameCount); Assert.AreEqual(399, mc.pos.x.ToInt()); CommandComponent cmd = new CommandComponent(); cmd.frame = 1; cmd.id = c1.ID; GlobalEvent.DispatchTypeEvent(cmd); world.CallRecalc(); world.FixedLoop(WorldManager.IntervalTime); mc = c1.GetComp <MoveComponent>(); //Debug.Log("mc.pos.x " + mc.pos.x + " frame " + world.FrameCount); for (int i = 0; i < 10; i++) { world.CallRecalc(); world.FixedLoop(WorldManager.IntervalTime); mc = c1.GetComp <MoveComponent>(); //Debug.Log("mc.pos.x " + mc.pos.x + " frame " + world.FrameCount); } Assert.AreEqual(0, mc.pos.x.ToInt()); }
public static bool GetClosestViableNode(Vector2d from, Vector2d dest, int pathingSize, out GridNode returnNode) { returnNode = GridManager.GetNode(dest.x, dest.y); if (returnNode.Unwalkable) { bool valid = false; PanLineAlgorithm.FractionalLineAlgorithm.Coordinate cacheCoord = new PanLineAlgorithm.FractionalLineAlgorithm.Coordinate(); bool validTriggered = false; pathingSize = (pathingSize + 1) / 2; int minSqrMag = pathingSize * pathingSize; minSqrMag *= 2; foreach (var coordinate in PanLineAlgorithm.FractionalLineAlgorithm.Trace(dest.x.ToDouble(), dest.y.ToDouble(), from.x.ToDouble(), from.y.ToDouble())) { currentNode = GridManager.GetNode(FixedMath.Create(coordinate.X), FixedMath.Create(coordinate.Y)); if (!validTriggered) { if (currentNode != null && currentNode.Unwalkable == false) { validTriggered = true; } else { cacheCoord = coordinate; } } if (validTriggered) { if (currentNode == null || currentNode.Unwalkable) { } else { //calculate sqrMag to last invalid node int testMag = coordinate.X - cacheCoord.X; testMag *= testMag; int buffer = coordinate.Y - cacheCoord.Y; buffer *= buffer; testMag += buffer; if (testMag >= minSqrMag) { valid = true; break; } } } } if (!valid) { return(false); } returnNode = currentNode; } return(true); }
public Command GenerateMovementCommand(float input) { if (this.IsTransitioning) { return(null); } Command com = new Command(this.Data.ListenInputID, this.Agent.Controller.ControllerID); com.Add <DefaultData> (new DefaultData(DataType.Long, FixedMath.Create(input))); return(com); }
public override void Execute() { LogicEntity e = Contexts.sharedInstance.logic.GetEntityWithId(entityID); LogicEntity hat = Contexts.sharedInstance.logic.GetEntityWithId(e.hat.entityID); if (hat == null) { return; } if (hat.isAttached) { hat.isAttached = false; hat.isDangerous = true; hat.isFalling = true; FixedVector2 throwdirection = axes.normalized; throwdirection = throwdirection.ContrainTo16Angles(); throwdirection = throwdirection.normalized; if (axes == FixedVector2.ZERO) { if (e.isWallRiding) { throwdirection = FixedVector2.LEFT * e.direction.value; } else { throwdirection = FixedVector2.RIGHT * e.direction.value; } } long extraPower = 0; if (e.velocity.value.y < 0 && axes.y < 0) { extraPower = e.velocity.value.y / 200; } hat.ReplaceVelocity(new FixedVector2( (hat.throwMovement.power + extraPower).Mul(throwdirection.x), (hat.throwMovement.power + extraPower).Mul(throwdirection.y) )); hat.throwMovement.throwPositionY = e.position.value.y; hat.ReplaceThrowTimer(FixedMath.Create(3, 10)); hat.ReplaceLastRotation(0); hat.ReplaceRotation(0); } }
public void Update() { if (_curTime > Length) { return; } long lx = LocalPositionX.Evaluate(_curTime); long ly = LocalPositionY.Evaluate(_curTime); long lz = LocalPositionZ.Evaluate(_curTime); Transform.localPosition = new Vector3(lx.ToFloat(), ly.ToFloat(), lz.ToFloat()); _curTime += FixedMath.Create(Time.deltaTime); }
//位置绕点旋转顺时针,逆时针角度乘以-1即可 public static Vector2d PostionRotateInXZ(this Vector2d pos, Vector2d center, long angle) { angle = -angle.Mul(FixedMath.Create(Mathf.Deg2Rad)); long cos = FixedMath.Trig.Cos(angle); long sin = FixedMath.Trig.Sin(angle); long x = (pos.x - center.x).Mul(cos) - (pos.y - center.y).Mul(sin) + center.x; long y = (pos.x - center.x).Mul(sin) + (pos.y - center.y).Mul(cos) + center.y; Vector2d newPos = new Vector2d(x, y); return(newPos); }
// Update is called once per frame void Update() { var aabb = new AABB(new Vector2d(FixedMath.Create(points[3].transform.position.x), FixedMath.Create(points[3].transform.position.y)), FixedMath.One, FixedMath.One); aabb.DrawAABB(0, 0.01f); bool rst = AABB.TestTriangle(new Vector2d(FixedMath.Create(points[0].transform.position.x), FixedMath.Create(points[0].transform.position.y)), new Vector2d(FixedMath.Create(points[1].transform.position.x), FixedMath.Create(points[1].transform.position.y)), new Vector2d(FixedMath.Create(points[2].transform.position.x), FixedMath.Create(points[2].transform.position.y)), aabb, 0 ); DLog.Log(rst.ToString()); }
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { SerializedProperty angle = property.FindPropertyRelative("_angle"); SerializedProperty timescaled = property.FindPropertyRelative("_timescaled"); double scale = LSEditorUtility.Scale(timescaled.boolValue); angle.doubleValue = EditorGUILayout.DoubleField(label, angle.doubleValue * scale) / scale; timescaled.boolValue = EditorGUILayout.Toggle("Timescaled", timescaled.boolValue); double angleInRadians = angle.doubleValue * Math.PI / 180d; property.FindPropertyRelative("_cos").longValue = FixedMath.Create(Math.Cos(angleInRadians)); property.FindPropertyRelative("_sin").longValue = FixedMath.Create(Math.Sin(angleInRadians)); }
//向量顺时针 public static Vector2d Vector2dRotateInXZ2(this Vector2d dir, long angle) { angle = angle.Mul(FixedMath.Create(Mathf.Deg2Rad)); long cos = FixedMath.Trig.Cos(angle); long sin = FixedMath.Trig.Sin(angle); long l_n_dirX = dir.x.Mul(cos) + dir.y.Mul(sin); long l_n_dirY = -dir.x.Mul(sin) + dir.y.Mul(cos); Vector2d l_dir = new Vector2d(l_n_dirX, l_n_dirY); return(l_dir); }
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { double scale = ((FixedNumberAngleAttribute)this.attribute).Timescaled ? LockstepManager.FrameRate : 1; double angle = Math.Round(Math.Asin(property.longValue.ToDouble()) * RadToDeg, 2, MidpointRounding.AwayFromZero); angle = EditorGUI.DoubleField(position, label, angle * scale) / scale; double max = ((FixedNumberAngleAttribute)this.attribute).Max; if (max > 0 && angle > max) { angle = max; } property.longValue = FixedMath.Create(Math.Sin(DegToRad * angle)); }
public Body(long leftBound, long rightBound, long downBound, long upBound) { //Debug.Log(" " + leftBound.ToFloat() + " " + rightBound.ToFloat() + " " + downBound.ToFloat() + " " + upBound.ToFloat()); bodyType = BodyType.Rectangle; isStandard = true; direction = new Vector2d(1, 0); length = rightBound - leftBound; width = upBound - downBound; position = new Vector2d(leftBound + (length).Div(FixedMath.Create(2)), downBound + (width).Div(FixedMath.Create(2))); //Debug.Log(" pos " + position + " l " + length.ToFloat() + " w " + width.ToFloat()); }
/* * 如果某一个象限(节点)内存储的物体数量超过了MAX_OBJECTS最大数量,则需要对这个节点进行划分 * */ public void Split() { long x = m_body.position.x; long y = m_body.position.y; long sl = m_body.length.Div(FixedMath.Create(2)); long sw = m_body.width.Div(FixedMath.Create(2)); //Debug.Log("Split " + x.ToFloat() + " " + y.ToFloat() + " " + sw.ToFloat() + " " + sl.ToFloat()); m_childList.Add(new QuadTree(new Body(x - sl, x, y - sw, y), m_depth + 1)); m_childList.Add(new QuadTree(new Body(x - sl, x, y, y + sw), m_depth + 1)); m_childList.Add(new QuadTree(new Body(x, x + sl, y - sw, y), m_depth + 1)); m_childList.Add(new QuadTree(new Body(x, x + sl, y, y + sw), m_depth + 1)); m_childListCount = 4; }
void UpdateMove(EntityBase entity, int deltaTime) { MoveComponent mc = (MoveComponent)entity.GetComp("MoveComponent"); CommandComponent cc = (CommandComponent)entity.GetComp("CommandComponent"); mc.dir = cc.moveDir; mc.m_velocity = 4000; Vector2d newPos = mc.pos; newPos += mc.dir * FixedMath.Create(deltaTime).Div(FixedMath.Create(1000)).Mul(FixedMath.Create(mc.m_velocity).Div(FixedMath.Create(1000))); mc.pos = newPos; //Debug.Log("dir " + mc.dir + " "); }
public static bool SearchNearEmptyPoint(Vector3d posi, out Vector3d target) { int x, y; GetCoordinate(posi, out x, out y); if (IsEmpty(x, y)) { target = new Vector3d(FixedMath.Create(x), 0, FixedMath.Create(y)) + Offset; return(true); } int radius = 1; while (true) { for (int i = radius; i >= -radius; i--) { for (int j = radius; j >= -radius; j--) { if (i != radius && i != -radius) { if (j == radius || j == -radius) { if (IsEmpty(j + x, i + y)) { target = (new Vector3d(FixedMath.Create(j + x), 0, FixedMath.Create(i + y)) + Offset) * CellSize; return(true); } } } else { if (IsEmpty(j + x, i + y)) { target = (new Vector3d(FixedMath.Create(j + x), 0, FixedMath.Create(i + y)) + Offset) * CellSize; return(true); } } } } radius++; if (radius > 10) { target = posi; return(false); } } }
public void Normal() { //Debug.Log(direction.GetRotationAngle(new Vector2d(1, 0)).ToFloat()); //Debug.Log(direction.GetRotationAngle(new Vector2d(-1, 0)).ToFloat()); //Debug.Log(direction.GetRotationAngle(new Vector2d(0, 1)).ToFloat()); //Debug.Log(direction.GetRotationAngle(new Vector2d(0, -1)).ToFloat()); if (FixedMath.Abs(direction.GetRotationAngle(new Vector2d(1, 0))) < FixedMath.Create(10) || direction == new Vector2d(1, 0) ) { direction = new Vector2d(1, 0); isStandard = true; } if (FixedMath.Abs(direction.GetRotationAngle(new Vector2d(-1, 0))) < FixedMath.Create(10) || direction == new Vector2d(-1, 0) ) { direction = new Vector2d(1, 0); isStandard = true; } if (FixedMath.Abs(direction.GetRotationAngle(new Vector2d(0, 1))) < FixedMath.Create(10) || direction == new Vector2d(0, 1) ) { direction = new Vector2d(1, 0); isStandard = true; long tmp = length; length = width; width = tmp; } if (FixedMath.Abs(direction.GetRotationAngle(new Vector2d(0, -1))) < FixedMath.Create(10) || direction == new Vector2d(0, -1) ) { direction = new Vector2d(1, 0); isStandard = true; long tmp = length; length = width; width = tmp; } }
public void Execute() { foreach (LogicEntity e in _stunTimers.GetEntities()) { if (e.stunTimer.timeLeft <= FixedMath.Create(3, 10)) { long acceleration = FixedMath.Lerp( e.stunMovement.accelerationTime, e.groundMovement.accelerationTime, e.stunTimer.timeLeft.Mul(FixedMath.Create(3, 10))); e.ReplaceCurrentMovementX(0, acceleration, e.currentMovementX.refSpeed); } e.ReplaceStunTimer(e.stunTimer.timeLeft - GameController.DELTA_TIME); } }
private void OnLoded(object sender, EventMsg msg) { _hasInited = true; EventGroup.DelEvent(SceneEvent.OnLoaded.ToInt(), OnLoded); var so = CreateSceneObject(); var modelComp = new ModelComponent(); modelComp.RePath = "kachujin.prefab"; so.AddComponent(modelComp); so.AddComponent <MainPlayerComponent>(); so.AddComponent <GravityComponent>(); so.AddComponent <StateMachine>(); so.AddComponent <AttributeManager>(); so.AttributeManager.SetBase(AttributeType.MaxSpeed, FixedMath.One * 2); so.Position = new Vector3d(FixedMath.Create(16.5f), FixedMath.One * 12, 0); var aabb = new AABBComponent(); aabb.AABB = new AABB(new Vector2d(FixedMath.One * 15, FixedMath.One * 15 + FixedMath.Half), FixedMath.One, FixedMath.One); so.AddComponent(aabb); }
public virtual void OnCollisionEnter(RaycastCollisionInfo info) { LogicEntity e = Contexts.sharedInstance.logic.GetEntityWithId(entityID); if (e.isStunned && (info.left != Tag.NONE || info.right != Tag.NONE) && !info.CollidesWithHorizontal(Tag.HAT)) { e.ReplaceVelocity(new FixedVector2( -e.velocity.value.x.Mul(FixedMath.Create(7, 10)), e.velocity.value.y + (e.velocity.value.y.Sign() * (e.velocity.value.x.Abs() / 2))) ); return; } else if ((info.up != Tag.NONE || info.down != Tag.NONE) && !info.CollidesWithVertical(Tag.HAT)) { e.ReplaceVelocity(e.velocity.value.SetY(0)); } }
public override void Execute(SceneObject sender, SceneObject reciever, object data) { var r = FixedMath.Create(Radius) / 100; var q = FixedQuaternion.LookRotation(sender.Forward, Vector3d.up); Utility.List.Clear(); var _battleScene = LogicCore.SP.SceneManager.CurrentScene as BattleScene; _battleScene.FixedQuadTree.Query(sender as IFixedAgent, r, Utility.List); for (int i = 0; i < Utility.List.Count; i++) { if (IsTarget(Utility.List[i])) { if (Utility.PositionIsInFan(sender.Position, FixedMath.Create(Radius) / 100, Angle, q, Utility.List[i].Position)) { EventManager.TriggerEvent(EventId, new RuntimeData(sender, Utility.List[i] as SceneObject, null)); } } } ; base.Execute(sender, reciever, data); }
//获取一个顺时针夹角(需先标准化向量) public static long GetRotationAngle(this Vector2d dir, Vector2d aimDir) { //dir = dir.normalized; //aimDir = aimDir.normalized; long angle = FixedMath.Create(Math.Acos(dir.Dot(aimDir).ToFloat())).Mul(FixedMath.Create(180).Div(FixedMath.Create(Math.PI))); if (angle != FixedMath.Create(180) && FixedMath.Create(angle) != 0) { long cross = dir.x.Mul(aimDir.y) - aimDir.x.Mul(dir.y); if (cross < FixedMath.Create(0)) { return(angle); } else { return(FixedMath.Create(360) - angle); } } return(angle); }
void Start() { for (int i = 0; i < 1000; i++) { var ra = UnityEngine.Random.Range(0, 1000f); var v1 = Mathf.Sin(ra * Mathf.Deg2Rad); var v2 = FixedMath.Trig.SinDegree(FixedMath.Create(ra)); // Debug.LogError(ra+" "+v1+" "+v2.ToFloat()); } var f = transform.forward; Vector3 nf = Vector3.zero; nf.x = f.x * Mathf.Cos(Angle * Mathf.Deg2Rad) + f.z * Mathf.Sin(Angle * Mathf.Deg2Rad); nf.z = f.z * Mathf.Cos(Angle * Mathf.Deg2Rad) - f.x * Mathf.Sin(Angle * Mathf.Deg2Rad); transform.forward = nf; // StringBuilder sb = new StringBuilder(1024); //for (int i = 0; i <= 360; i++) //{ // var cos = Mathf.Cos(i * Mathf.Deg2Rad); // var fcos = FixedMath.Create(cos); // sb.Append("{"+FixedMath.Create(i)+","+fcos+ "},"); //} // File.WriteAllText("D://cos.txt", sb.ToString()); }
public List <Vector2d> GetRectPoint(Body rect) { listCache.Clear(); if (rect.isStandard) { listCache.Add(new Vector2d(rect.position.x + rect.length.Mul(FixedMath.Half), rect.position.y + rect.width.Mul(FixedMath.Half))); listCache.Add(new Vector2d(rect.position.x + rect.length.Mul(FixedMath.Half), rect.position.y - rect.width.Mul(FixedMath.Half))); listCache.Add(new Vector2d(rect.position.x - rect.length.Mul(FixedMath.Half), rect.position.y + rect.width.Mul(FixedMath.Half))); listCache.Add(new Vector2d(rect.position.x - rect.length.Mul(FixedMath.Half), rect.position.y - rect.width.Mul(FixedMath.Half))); } else { Vector2d forward = rect.direction * rect.length.Mul(FixedMath.Half); Vector2d left = rect.direction.Vector2dRotateInXZ(FixedMath.Create(90)) * rect.length.Mul(FixedMath.Half); listCache.Add(rect.position + forward + left); listCache.Add(rect.position + forward - left); listCache.Add(rect.position - forward + left); listCache.Add(rect.position - forward - left); } return(listCache); }