void Awake() { // add our one-way platforms to our normal platform mask so that we can land on them from above platformMask |= oneWayPlatformMask; // cache some components tfTransform = GetComponent <TFTransform>(); boxCollider = GetComponent <TFPolygonCollider>(); rigidBody2D = GetComponent <TFRigidbody>(); if (rigidBody2D) { rigidBody2D.OnTriggerEnter += TFOnTriggerEnter; rigidBody2D.OnTriggerStay += TFOnTriggerStay; rigidBody2D.OnTriggerExit += TFOnTriggerExit; } // here, we trigger our properties that have setters with bodies skinWidth = _skinWidth; // we want to set our CC2D to ignore all collision layers except what is in our triggerMask for (var i = 0; i < 32; i++) { // see if our triggerMask contains this layer and if not ignore it if ((triggerMask.mask & 1 << i) == 0) { Physics2D.IgnoreLayerCollision(gameObject.layer, i); } } }
internal TFRaycastHit2D Raycast(ITreeRaycastCallback callback, FixVec2 pointA, FixVec2 pointB, TFLayerMask mask) { TFRaycastHit2D hit = new TFRaycastHit2D(); FixVec2 r = pointB - pointA; if (r.GetMagnitudeSquared() <= Fix.zero) { return(hit); } r.Normalize(); // v is perpendicular to the segment. FixVec2 v = FixVec2.Cross(Fix.one, r); FixVec2 abs_v = FixVec2.Abs(v); // Separating axis for segment (Gino, p80). // |dot(v, p1 - c)| > dot(|v|, h) Fix maxFraction = Fix.one; // Build a bounding box for the segment. AABB segmentAABB = new AABB(); FixVec2 t = pointA + maxFraction * (pointB - pointA); segmentAABB.min = FixVec2.Min(pointA, t); segmentAABB.max = FixVec2.Max(pointA, t); Stack <int> stack = new Stack <int>(); stack.Push(rootIndex); List <TFRaycastOutput> hitNodes = new List <TFRaycastOutput>(2); while (stack.Count > 0) { var nodeId = stack.Pop(); if (nodeId == nullNode) { continue; } var node = nodes[nodeId]; if (!node.aabb.Overlaps(segmentAABB)) { continue; } // Separating axis for segment (Gino, p80). // |dot(v, p1 - c)| > dot(|v|, h) var c = node.aabb.GetCenter(); var h = node.aabb.GetExtents(); var separation = FixMath.Abs(FixVec2.Dot(v, pointA - c)) - FixVec2.Dot(abs_v, h); if (separation > Fix.zero) { continue; } if (node.IsLeaf()) { // If value is >= 0, then we hit the node. TFRaycastHit2D rHit; Fix value = callback.RayCastCallback(pointA, pointB, maxFraction, nodeId, out rHit, mask); if (value == Fix.zero) { // The client has terminated the ray cast. if (rHit) { // We actually hit the node, add it to the list. hitNodes.Add(new TFRaycastOutput(nodeId, rHit)); } break; } if (value == maxFraction) { if (rHit) { // We actually hit the node, add it to the list. hitNodes.Add(new TFRaycastOutput(nodeId, rHit)); } } else if (value > Fix.zero) { if (rHit) { // We actually hit the node, add it to the list. hitNodes.Add(new TFRaycastOutput(nodeId, rHit)); } // Update segment bounding box. maxFraction = value; FixVec2 g = pointA + maxFraction * (pointB - pointA); segmentAABB.min = FixVec2.Min(pointA, g); segmentAABB.max = FixVec2.Max(pointA, g); } } else { stack.Push(node.leftChildIndex); stack.Push(node.rightChildIndex); } } // Decide which node was the closest to the starting point. Fix closestNode = maxFraction; for (int i = 0; i < hitNodes.Count; i++) { if (hitNodes[i].hit.fraction < closestNode) { closestNode = hitNodes[i].hit.fraction; hit = hitNodes[i].hit; } } return(hit); }
public Fix RayCastCallback(FixVec2 pointA, FixVec2 pointB, Fix maxFraction, int proxyID, out TFRaycastHit2D hit, TFLayerMask mask) { TFRigidbody rigid = bodies[dynamicTree.nodes[proxyID].bodyIndex]; if (!(mask == (mask | (1 << rigid.layer)))) { // This object is not in the mask, ignore it. hit = new TFRaycastHit2D(); return(maxFraction); } rigid.coll.Raycast(out hit, pointA, pointB, maxFraction); if (!hit) { // We did not hit the body, ignore it and use our max ray length. return(maxFraction); } Fix fraction = hit.fraction; FixVec2 point = (Fix.one - fraction) * pointA + fraction * pointB; hit.point = point; hit.distance = (point - pointA).GetMagnitude(); return(RayCastCallback(rigid, hit.point, hit.normal, hit.fraction)); }
public TFRaycastHit2D Raycast(FixVec2 origin, FixVec2 direction, Fix distance, TFLayerMask mask) { TFRaycastHit2D hit = dynamicTree.Raycast(this, origin, origin + direction * distance, mask); return(hit); }
public static TFRaycastHit2D Raycast(FixVec2 origin, FixVec2 direction, Fix distance, TFLayerMask mask) { TFRaycastHit2D hit = physicsScene.Raycast(origin, direction, distance, mask); return(hit); }