public virtual void Init(int pGuid) { vGuid = pGuid; mTransform = transform; vRigidBody = gameObject.GetComponent<Rigidbody>(); vColliderInfo = gameObject.GetComponent<ColliderInfo>(); }
public void AddCollider(ColliderInfo pColliderInfo) { if (mColliderPools.Count > 0) pColliderInfo.vGuid = mColliderPools.Pop(); else pColliderInfo.vGuid = mColliderInfos.Count; mColliderInfos.Add(pColliderInfo); }
public bool GetColliderInfo(Collider collider, out ColliderInfo info) { if (collider != null && colliderInfo.ContainsKey(collider)) { info = colliderInfo[collider]; return(true); } else { info = new ColliderInfo(); } return(false); }
private void MoveCollider(ColliderInfo item) { ServerCollider serverCollider; if (this.colliders.TryGetValue(item.name, out serverCollider)) { serverCollider.position.x = item.x; serverCollider.position.z = item.z; } else { this.CreateCollider(item); } }
//------------------------------------------------------------------------------------------------------------------------ // Remove() //------------------------------------------------------------------------------------------------------------------------ public void Remove(GameObject gameObject) { if (collisionLoopActive) { throw new Exception("Cannot destroy or remove gameobjects during OnCollision - use LateDestroy or LateRemove instead."); } colliderList.Remove(gameObject); if (_collisionReferences.ContainsKey(gameObject)) { ColliderInfo colliderInfo = _collisionReferences[gameObject]; activeColliderList.Remove(colliderInfo); _collisionReferences.Remove(gameObject); } }
void AddOrUpdateColliderInfo(Collider collider, ColliderInfo info) { // Note (Zak): This could be achieved in one line // just by doing colliderInfo[collider] = info; // but nobody likes it that way... :'( if (colliderInfo.ContainsKey(collider)) { colliderInfo[collider] = info; } else { colliderInfo.Add(collider, info); } }
/// <summary> /// Gather hypothetical collider information from solid flag. /// </summary> /// <param name="info">Collider information instance.</param> private void GatherInfo_SolidFlag(ColliderInfo info) { info.IsTrigger = false; // Bounds of 2D colliders need to be consistent. Vector3 boundsSize = this.system.CellSize; if (info.Type == ColliderType.BoxCollider2D) { boundsSize.z = 1f; } info.Bounds = BoxBounds.FromBounds(this.system.LocalPositionFromTileIndex(info.Row, info.Column), boundsSize); }
public SACollider(CollBase collider, ColliderInfo collidInfo, SkillActionParser actionParser, uint actFrame) : base(actionParser, actFrame) { _collider = collider; _colliderInfo = collidInfo; _effectCounter = new EffectCounter(); _colliderCount = 0; ColliderDestroy = false; ActionType = SkillDefine.SkillActionType.COLLIDER; _frameMax = _actFrame + collidInfo.LifeTime; CheckTargetList(); }
private void GetColliders(GameObject layer) { if (layer.GetComponentInChildren <MeshFilter>() == null) { Debug.LogError("no obstacle mesh!"); return; } Vector3[] vertices = layer.GetComponentInChildren <MeshFilter>().sharedMesh.vertices; int[] triangles = layer.GetComponentInChildren <MeshFilter>().sharedMesh.triangles; mapWidth = layer.transform.parent.GetComponent <TiledMap>().NumTilesWide; mapHeight = layer.transform.parent.GetComponent <TiledMap>().NumTilesHigh; for (int i = 1; i < triangles.Length; i += 3) { Vector3 v1 = vertices[triangles[i]]; Vector3 v2 = vertices[triangles[i + 1]]; if (!colliders.ContainsKey(v1.y)) { colliders.Add(v1.y, new List <ColliderInfo>()); } FindAndUpdateColliderBasedOnVertices(v1, v2); //Debug.Log(vertices[triangles[i-1]].x + ":" + vertices[triangles[i-1]].y + " , " + v1.x + ":" + v1.y + " , " + v2.x + ":" + v2.y); } MergeColliders(); GameObject collidersObj = new GameObject("colliders"); foreach (KeyValuePair <float, List <ColliderInfo> > elem in colliders) { for (int i = 0; i < elem.Value.Count; i++) { ColliderInfo colData = elem.Value[i]; BoxCollider2D col = collidersObj.AddComponent <BoxCollider2D>(); col.offset = new Vector2(colData.x + colData.width / 2, (colData.y - colData.height / 2)); col.size = new Vector2(colData.width, colData.height); collidersList.Add(colData); } } collidersObj.layer = LayerMask.NameToLayer("Walls"); collidersObj.tag = "Wall"; collidersObj.transform.parent = layer.transform; }
/// <summary> /// Get collider information from specific tile within tile system. Assigns a value /// of <c>null</c> to <paramref name="info"/> if tile does not contain a collider. /// </summary> /// <param name="info">Reference to variable that will contain collider information /// once this method has returned. Any existing <see cref="ColliderInfo"/> instance /// will be despawned.</param> /// <param name="row">Zero-based index of tile row.</param> /// <param name="column">Zero-based index of tile column.</param> private void GetColliderInfo(ref ColliderInfo info, int row, int column) { // Automatically return prior collider information to pool for reuse later. if (info != null) { ColliderInfo.Despawn(info); info = null; } // Only consider collider information for non-empty tiles which were painted // using a brush which has been marked "Static". var tile = this.system.GetTile(row, column); if (tile == null || tile.brush == null || !tile.brush.Static) { return; } // Gather information from collider component? if (tile.gameObject != null) { var boxCollider3D = tile.gameObject.GetComponentInChildren <BoxCollider>(); if (boxCollider3D != null) { info = ColliderInfo.Spawn(tile, row, column, ColliderType.BoxCollider3D); this.GatherInfo_BoxCollider3D(info, boxCollider3D); return; } else { var boxCollider2D = tile.gameObject.GetComponentInChildren <BoxCollider2D>(); if (boxCollider2D != null) { info = ColliderInfo.Spawn(tile, row, column, ColliderType.BoxCollider2D); this.GatherInfo_BoxCollider2D(info, boxCollider2D); return; } } } // Assume collider due to state of 'Solid' flag? if (this.system.ReduceColliders.IncludeSolidTiles && tile.SolidFlag) { info = ColliderInfo.Spawn(tile, row, column, this.system.ReduceColliders.SolidTileColliderType); this.GatherInfo_SolidFlag(info); return; } }
private static bool CheckFlags(List <Collider> list, ColliderInfo.Flags ignore) { for (int i = 0; i < list.Count; i++) { ColliderInfo component = list[i].gameObject.GetComponent <ColliderInfo>(); if (component == null) { return(true); } if (!component.HasFlag(ignore)) { return(true); } } return(false); }
private void _OnCollider(ColliderInfo pColliderInfo) { if (pColliderInfo.vType == ColliderType.Wall) { _OnDestroy(); } if (pColliderInfo.vType == ColliderType.Unit) { Unit lUnit = pColliderInfo.GetComponent<Unit>(); if (lUnit.vUnitTeamId != vColliderInfo.vValue) { lUnit.OnMissileCollider(this); _OnDestroy(); } } }
/// <summary> /// Gather collider information from <see cref="BoxCollider2D"/> component. /// </summary> /// <param name="info">Collider information instance.</param> /// <param name="collider">Component which resides somewhere within tile.</param> private void GatherInfo_BoxCollider2D(ColliderInfo info, BoxCollider2D collider) { var tileToSystemMatrix = this.worldToSystem * collider.transform.localToWorldMatrix; // Bounds of 2D colliders need to be consistent. Vector3 boundsSize = collider.size; boundsSize.z = 1f; Vector3 center = collider.offset; info.IsTrigger = collider.isTrigger; info.Material = collider.sharedMaterial; info.Collider = collider; info.Bounds = SpaceToSpace(BoxBounds.FromBounds(center, boundsSize), tileToSystemMatrix); }
private static bool CheckFlags(List <Collider> list, DeployVolume volume) { for (int i = 0; i < list.Count; i++) { GameObject gameObject = list[i].gameObject; if (gameObject.CompareTag("DeployVolumeIgnore")) { continue; } ColliderInfo component = gameObject.GetComponent <ColliderInfo>(); if (!(component == null) && volume.ignore != 0 && component.HasFlag(volume.ignore)) { continue; } if (volume.entityList.Length == 0) { return(true); } BaseEntity baseEntity = GameObjectEx.ToBaseEntity(list[i]); bool flag = false; if (baseEntity != null) { BaseEntity[] array = volume.entityList; foreach (BaseEntity baseEntity2 in array) { if (baseEntity.prefabID == baseEntity2.prefabID) { flag = true; break; } } } if (volume.entityMode == EntityMode.IncludeList) { if (flag) { return(true); } } else if (volume.entityMode == EntityMode.ExcludeList && !flag) { return(true); } } return(false); }
private void CreateCollider(ColliderInfo item) { if (this.colliders.ContainsKey(item.name)) { return; } ServerCollider serverCollider = new ServerCollider(); serverCollider.name = item.name; serverCollider.position = new Vector3(item.x, 2f, item.z); serverCollider.radius = item.radius; serverCollider.width = item.width; serverCollider.lenght = item.lenght; serverCollider.rotation = item.rotation; serverCollider.type = item.type; this.colliders.Add(item.name, serverCollider); }
private void AddColliders(List <ColliderInfo> colliderInfos, Part part) { printf("Adding part %s to collider list", part.name); foreach (Collider collider in part.GetPartColliders()) { ColliderInfo colliderInfo = new ColliderInfo(); colliderInfo.collider = collider; colliderInfo.part = part; colliderInfo.posRot = PosRot.GetPosRot(collider.transform, part); colliderInfos.Add(colliderInfo); } foreach (Part child in part.children) { AddColliders(colliderInfos, child); } }
/// <summary> /// Moves the player along the ledge if they made an input. /// Enables and disables DoClamberLedge and DiDJump based on whether you are looking into or away from the ledge /// </summary> /// <param name="ctrl">A reference to the player controller</param> protected override void StateUpdate(ref PlayerController ctrl) { //Get the horizontal input and the forward vector on the player but without the y component float x = InputManager.GetInput("Horizontal"); Vector3 forward = ctrl.transform.forward; forward.y = 0; forward.Normalize(); //Set our jump vector to be the way we are looking ctrl.ExpectedDir = forward; //If the player pressed space, is looking into the wall and there is space above the wall for the player, pull the player on top of the wall if (Vector3.Dot(forward, ctrl.CheckDir) >= 0) { //The player is looking into the wall ignoreTransition[didJumpIndex] = true; //Make sure there is space above the player if they want to pull up if (!ColliderInfo.Cast(ctrl.colInfo, ctrl.CheckDir * (ctrl.colInfo.Radius * 2), Vector3.up * (ctrl.colInfo.Radius + ctrl.colInfo.Height + ctrl.colInfo.CollisionOffset))) { ignoreTransition[doClamberLedgeIndex] = false; } else { ignoreTransition[doClamberLedgeIndex] = true; } Vector3 right = new Vector3(ctrl.CheckDir.z, ctrl.CheckDir.y, -ctrl.CheckDir.x); //Do a raycast from the side of the player into the wall, continue if it returns true. if (x != 0 && Physics.Raycast(ctrl.colInfo.GetHighestPoint() + right * (x * ctrl.colInfo.Radius), ctrl.CheckDir, ctrl.CheckDirRange + 0.01f)) { //Get the movement Vector Vector3 moveDir = right * x * ctrl.shimmySpeed * Time.deltaTime; //Do a raycast from above the player at the expected movement position, if it returns false, the ledge is still there so we are allowed to move if (Physics.Raycast(ctrl.colInfo.GetHighestPoint() + moveDir, ctrl.CheckDir, ctrl.CheckDirRange + 0.01f)) { //Move the player ctrl.MoveTo(moveDir, true); } } } else { //The player is not looking into the wall so disable the pull up transition and enable jumping ignoreTransition[didJumpIndex] = false; ignoreTransition[doClamberLedgeIndex] = true; } }
public void UpdateInfo(Vector2 newPosition, bool activeCollider, float collisionDamage, bool enabled) { this.enabled = enabled; this.collisionDamage = collisionDamage; bool nowActive = false; if (!this.activeCollider && activeCollider) { nowActive = true; } this.activeCollider = activeCollider; ColliderEvent[] colliderEvents = collider.Translate(newPosition, ignoreCurrentlyColliding: nowActive); if (enabled && activeCollider) { //Find associated clients NetworkEntity[] networkEntities = lobby.NetworkEntities.Where(t => t is ServerCollider).ToArray(); ColliderInfo[] collidedInfo = new ColliderInfo[colliderEvents.Length]; for (int i = 0; i < collidedInfo.Length; i++) { for (int j = 0; j < networkEntities.Length; j++) { if (networkEntities[j] is ServerCollider b && b.IsEnabled && b.collider == colliderEvents[i].CollidedWith) { collidedInfo[i] = b.ColliderInfo; break; } } } //Forward to associated clients ColliderInfo colliderInfo = ColliderInfo; for (int i = 0; i < collidedInfo.Length; i++) { if (collidedInfo[i] != null) { //Send message to both involved CollidedMessage collidedMessage = new CollidedMessage(collidedInfo[i], colliderInfo, colliderEvents[i].CollisionPoint); lobby.SendToClient(collidedInfo[i].clientIndex, collidedMessage); lobby.SendToClient(ClientIndex, collidedMessage); } } } }
/// <summary> /// Determine whether input colliders could be reduced assuming that they /// are geometrically compatible. /// </summary> /// <remarks> /// <para>Colliders cannot be reduced under the following circumstances:</para> /// <list type="bullet"> /// <item>Either <paramref name="a"/> or <paramref name="b"/> was a value of <c>null</c> /// indicating that at least one of the parameters represents a tile which does not /// contain a collider that can be reduced.</item> /// <item><paramref name="a"/> and <paramref name="b"/> represent different types of /// collider; for instance, a <see cref="BoxCollider"/> and a <see cref="BoxCollider2D"/> /// are not compatible.</item> /// <item>One collider represents a trigger whilst the other doesn't. These cannot be /// combined since it would affect game behaviour.</item> /// <item>Input colliders have a different physics material which cannot be combined /// since it would affect game behaviour.</item> /// <item><see cref="TileSystem.ReduceColliders">TileSystem.ReduceColliders</see> can /// prevent colliders from being reduced if they have a different tag or layer.</item> /// </list> /// </remarks> /// <param name="a">Information for first collider.</param> /// <param name="b">Information for second collider.</param> /// <returns> /// A value of <c>true</c> if input colliders can be reduced; otherwise, a /// value of <c>false</c>. /// </returns> private bool CanReduce(ColliderInfo a, ColliderInfo b) { if (a == null || b == null || a.Type != b.Type || a.IsTrigger != b.IsTrigger || a.Material != b.Material) { return(false); } var goA = a.Tile.gameObject; var goB = b.Tile.gameObject; // Hypothetical colliders can be reduced without having to determine whether // tags or layers are to be kept separate. if (goA == null || goB == null) { return(true); } return((!this.separateByTag || goA.tag == goB.tag) && (!this.separateByLayer || goA.layer == goB.layer)); }
/// <summary> /// Performs a capsual cast using the given colliderInfo with collisionOffset /// </summary> /// <param name="c">The collider to cast</param> /// <param name="castVec">The direction and distance to cast the collider</param> /// <param name="offset">The offset from origin the cast should take place</param> /// <param name="hit">Information about the object that was hit</param> /// <returns>Returns true if something was hit</returns> public static bool CastWithOffset(ColliderInfo c, Vector3 castVec, Vector3 offset, out RaycastHit hit) { //Perform the raycast RaycastHit[] h = CastAllWithOffset(c, castVec, offset); hit = new RaycastHit(); //If h is null or has a length of 0, return false if (h == null || h.Length == 0) { return(false); } //Loop through the results to find the first valid result and return it for (int i = 0; i < h.Length; i++) { if (h[i].distance != 0) { hit = h[i]; return(true); } } //Return false if none of the hit results were valid return(false); }
/// <summary> /// Performs a capsual cast using the given colliderInfo /// </summary> /// <param name="c">The collider to cast</param> /// <param name="castVec">The direction and distance to cast the collider</param> /// <param name="offset">The offset from origin the cast should take place</param> /// <param name="hit">Information about the object that was hit</param> /// <returns>Returns true if something was hit</returns> public static bool Cast(ColliderInfo c, Vector3 castVec, Vector3 offset, out RaycastHit hit) { //Perform the raycast and get the results RaycastHit[] h = CastAll(c, castVec, offset); hit = new RaycastHit(); //If h hit nothing return false if (h == null || h.Length == 0) { return(false); } //Loop through the results and and find the closest valid result for (int i = 0; i < h.Length; i++) { //If the distance is not 0, return the hit value if (h[i].distance != 0) { hit = h[i]; return(true); } } return(false); }
public void DebugCollider(ColliderInfo item) { if (item == null) { return; } switch (item.code) { case 1: this.CreateCollider(item); break; case 2: this.MoveCollider(item); break; case 3: this.DestroyCollider(item); break; } }
//------------------------------------------------------------------------------------------------------------------------ // Add() //------------------------------------------------------------------------------------------------------------------------ public void Add(GameObject gameObject) { if (gameObject.collider != null && !colliderList.Contains (gameObject)) { colliderList.Add(gameObject); } MethodInfo info = gameObject.GetType().GetMethod("OnCollision", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); if (info != null) { CollisionDelegate onCollision = (CollisionDelegate)Delegate.CreateDelegate(typeof(CollisionDelegate), gameObject, info, false); if (onCollision != null && !_collisionReferences.ContainsKey (gameObject)) { ColliderInfo colliderInfo = new ColliderInfo(gameObject, onCollision); _collisionReferences[gameObject] = colliderInfo; activeColliderList.Add(colliderInfo); } } else { validateCase(gameObject); } }
//------------------------------------------------------------------------------------------------------------------------ // Step() //------------------------------------------------------------------------------------------------------------------------ public void Step() { collisionLoopActive = SafeCollisionLoop; for (int i = activeColliderList.Count - 1; i >= 0; i--) { ColliderInfo info = activeColliderList[i]; if (!info.gameObject.Enabled) { continue; } for (int j = colliderList.Count - 1; j >= 0; j--) { if (j >= colliderList.Count) { continue; //fix for removal in loop } GameObject other = colliderList[j]; if (!other.Enabled) { continue; } if (info.gameObject != other) { if (info.gameObject.HitTest(other)) { if (info.onCollision != null) { info.onCollision(other); } } } } } collisionLoopActive = false; }
public bool PointSeePoint(Vector3 target, Vector3 origin, float dist = 0f, bool useGameTrace = false) { bool flag = false; if (dist == 0f) { dist = Vector3.Distance(target, origin); } Vector3 normalized = (target - origin).normalized; Ray ray = new Ray(origin, normalized); RaycastHit raycastHit; if ((!useGameTrace) ? Physics.Raycast(ray, out raycastHit, dist, 10551297) : GamePhysics.Trace(ray, 0f, out raycastHit, dist, 10551297, QueryTriggerInteraction.UseGlobal)) { ColliderInfo component = raycastHit.collider.GetComponent <ColliderInfo>(); if (component == null || component.HasFlag(ColliderInfo.Flags.VisBlocking)) { flag = true; } } return(!flag); }
//------------------------------------------------------------------------------------------------------------------------ // Add() //------------------------------------------------------------------------------------------------------------------------ public void Add(GameObject gameObject) { if (gameObject.collider != null) { colliderList.Add(gameObject); } MethodInfo info = gameObject.GetType().GetMethod("OnCollision", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); if (info != null) { CollisionDelegate onCollision = (CollisionDelegate)Delegate.CreateDelegate(typeof(CollisionDelegate), gameObject, info, false); if (onCollision != null) { ColliderInfo colliderInfo = new ColliderInfo(gameObject, onCollision); _collisionReferences[gameObject] = colliderInfo; activeColliderList.Add(colliderInfo); } } else { validateCase(gameObject); } }
/// <summary> /// Performs the raycasts to detect collisions for MoveTo /// </summary> /// <param name="dir">The direction & magnitude of the raycasts</param> /// <param name="offsetIndex">The index that the output hitInfo is from the second raycast instead of the first</param> /// <returns>An array containing hitInfo from two raycasts. One with radius, the other with radius + offset</returns> private RaycastHit[] MoveToRaycasts(Vector3 dir, out int offsetIndex) { //Raycast for the players regular collider RaycastHit[] regular = ColliderInfo.CastAll(colInfo, dir); //Raycast for the players collider with the offset RaycastHit[] withOffset = ColliderInfo.CastAllWithOffset(colInfo, dir); //Sort them by distance. Closest ones should be checked first System.Array.Sort(regular, Conditions.CompareDist); System.Array.Sort(withOffset, Conditions.CompareDist); //Combine the raycast results RaycastHit[] total = new RaycastHit[regular.Length + withOffset.Length]; for (int i = 0; i < total.Length; i++) { if (i >= regular.Length) { total[i] = withOffset[i - regular.Length]; } else { total[i] = regular[i]; } } offsetIndex = regular.Length; return(total); }
/// <summary> /// Check for 'T' junction of combinable tile colliders. /// </summary> /// <param name="firstInfo">Collider information for first tile in horizontal sequence.</param> /// <param name="lastInfo">Collider information for last tile in horizontal sequence.</param> /// <returns> /// A value of <c>true</c> if T-junction was detected; otherwise, a value of <c>false</c>. /// </returns> private bool CheckForTJunction(ColliderInfo firstInfo, ColliderInfo lastInfo) { if (firstInfo.Column == 0 || lastInfo.Column + 1 == this.system.ColumnCount) { return(false); } if (this.markedTiles[firstInfo.Row, firstInfo.Column - 1] || this.markedTiles[lastInfo.Row, lastInfo.Column + 1]) { return(false); } ColliderInfo leftInfo = null, rightInfo = null; try { this.GetColliderInfo(ref leftInfo, firstInfo.Row, firstInfo.Column - 1); if (!this.CanReduce(leftInfo, firstInfo)) { return(false); } this.GetColliderInfo(ref rightInfo, lastInfo.Row, lastInfo.Column + 1); if (!this.CanReduce(rightInfo, firstInfo)) { return(false); } return(leftInfo.Bounds.Encapsulate(firstInfo.Bounds) && lastInfo.Bounds.Encapsulate(rightInfo.Bounds) ); } finally { ColliderInfo.Despawn(leftInfo); ColliderInfo.Despawn(rightInfo); } }
private void OnTriggerEnter2D(Collider2D collider) { if (!enabled || collider.gameObject.layer != (int)PhysLayers.ENEMIES) { return; } IHitResponder hit = collider.gameObject.GetComponentInSelfChildOrParent <IHitResponder>(); ColliderInfo colInfo = _hitReponders.FirstOrDefault(info => info.Responder == hit); if (colInfo == null) { colInfo = new ColliderInfo { Responder = hit, Cooldown = 0 }; _hitReponders.Add(colInfo); } colInfo.Touching = true; }
public void RemoveCollider(ColliderInfo pColliderInfo) { mColliderPools.Push(pColliderInfo.vGuid); mColliderInfos.Remove(pColliderInfo); }
private void _OnCollider(ColliderInfo pColliderInfo) { bool lIsDamaged = false; if (pColliderInfo.vType == ColliderType.Missile && pColliderInfo.vValue != vUnitTeamId) { Missile lMissile = pColliderInfo.GetComponent<Missile>(); vHp -= lMissile.vPower; lIsDamaged = true; } else if (pColliderInfo.vType == ColliderType.Unit && pColliderInfo.vValue != vUnitTeamId) { vHp -= 1; lIsDamaged = true; } // HP 처리 if (lIsDamaged) { if (vHp <= 0) { mIsStiff = true; GoDie(); } else { mIsStiff = true; vAnim.CrossFade("GoDown", 0.1f, 0, 0.5f); } } }
private void _OnPickObject(ColliderInfo pColliderInfo) { if(pColliderInfo.vType == ColliderType.Unit && pColliderInfo.vValue == 1) { vTargetObject = pColliderInfo.transform; } }
bool GetPolygonCollider(ColliderInfo ci) { var g = ci.cornerGraph; var n = g.nodes[0]; if (g.nodes.Count == 1) { var pos = (Vector2)n.value.position; var pts = new Vector2[] { pos, pos + Vector2.up, pos + Vector2.one, pos + Vector2.right }; ci.points = pts; ci.position = pos; return(true); } else { int dir = 1; bool found = false; for (; dir < 8; dir += 2) { var nbr = n.value.neighbours[dir]; if (nbr == null || nbr.IsEmpty) { found = true; } else if (found && nbr != null && !nbr.IsEmpty) { break; } } int start = dir % 8; n = GetNext(g, n, start); var n0 = n; var pts = new List <Vector2>(); do { var next = dir + 6; var end = next + 8; var pos = (Vector2)n.value.position; for (; next < end; next = next + 2) { var nbr = n.value.neighbours[next % 8]; if (nbr == null || nbr.IsEmpty) { if (next > dir + 6) { pts.Add(pos + GetQuadCorner((next + 6) % 8)); } } else if (nbr != null && !nbr.IsEmpty) { if (next == dir + 6) { pts.Add(pos + GetQuadCorner((dir + 4) % 8)); } break; } } if (next != end) { dir = next % 8; var nn = GetNext(g, n, dir); if (nn == null) { n.value.status = string.Format("Tile missing neighbour! {0}", dir); Debug.LogErrorFormat("Tile missing neighbour! {0}", dir); break; } n = nn; } } while (n0 != n || start != dir); if (n != null && pts.Count > 0) { var pos = (Vector2)n.value.position; var path = new Vector2[pts.Count]; for (int i = 0; i < pts.Count; i++) { path[i] = pts[i]; } ci.points = path; ci.position = pos; return(true); } } return(false); }
void BuildEdgeGraph() { edgeGraph = new Graph <Tile>(currentTiles); edgeGraph.Filter(t => !t.value.IsEmpty && t.value.HasNeighbour(n => n == null || n.IsEmpty, true)); edgeGraph.Connect((t, l) => { foreach (var n in t.neighbours) { // only connect nodes with the same collision type and which are not empty or diagonal to each other if (n != null && (!t.IsDiagonal(n)) && edgeGraph.Contains(n) && n.data.collisions == t.data.collisions) { l.Add(n); } } }); edgeGraph.BFS(); colliders = new List <ColliderInfo>(); Debug.Log(edgeGraph.forest.Count); int e0 = 0, e1 = 0; // build a graph representing the perimeter of each connected grid foreach (var g in edgeGraph.forest) { if (e0++ > 1000) { break; } e1 = 0; var nl = new Graph <Tile>(); for (int i = 0; i < g.nodes.Count; i++) { var n = g.nodes[i]; bool added = false; for (int ni = 1; ni < 8 && !added; ni += 2) { var e = n.value.neighbours[ni]; if (e == null || e.IsEmpty) { // get left and right neighbours var li = (ni + 2) % 8; var ri = (ni - 2 + 8) % 8; var l = n.value.neighbours[li]; var r = n.value.neighbours[ri]; // treat tiles off the edge as empty tiles // if either both neighbours are empty or neither, this is an important corner var rc = r == null || r.IsEmpty; var lc = l == null || l.IsEmpty; if (rc || lc) { nl.Add(n.value); added = true; } } } if (!added) { for (int ni = 0; ni < 8 && !added; ni += 2) { var e = n.value.neighbours[ni]; if (e == null || e.IsEmpty) { // get left and right neighbours var li = (ni + 1) % 8; var ri = (ni - 1 + 8) % 8; var l = n.value.neighbours[li]; var r = n.value.neighbours[ri]; // treat tiles off the edge as empty tiles // if either both neighbours are empty or neither, this is an important corner var rc = r == null || r.IsEmpty; var lc = l == null || l.IsEmpty; if (rc == lc) { nl.Add(n.value); added = true; } } } } if (added) { for (int ni = 0; ni < 4; ni++) { var t = n.value.neighbours[ni * 2 + 1]; for (int s = 0; s < 100; s++) { if (t == null || t.IsEmpty) { break; } else if (nl.Contains(t)) { nl.Connect(n.value, t); break; } else { t = t.neighbours[ni * 2 + 1]; } } } } } if (nl.nodes.Count > 0) { var ci = new ColliderInfo(nl); colliders.Add(ci); } } Debug.Log(colliders.Count); }
protected override void OnCollision(GameSession gameSession, ColliderInfo collidedInfo, ColliderInfo colliderInfo, Vector2 collisionPosition, bool amCollided) { if (amCollided) { //Knockback float angleOfCollision = (float)Math.Atan2(colliderInfo.colliderPosition.Y - rigidBody.CollisionPolygon.CenterPoint.Y, colliderInfo.colliderPosition.X - rigidBody.CollisionPolygon.CenterPoint.X); Vector2 velocityVector = new Vector2(-(float)Math.Cos(angleOfCollision), -(float)Math.Sin(angleOfCollision) - .5F); rigidBody.AddTranslationalVelocity(velocityVector); if (colliderInfo.colliderPosition.X < rigidBody.CollisionPolygon.CenterPoint.X) { SpriteManager.FacingState = SpriteManager.FacingStates.Left; } else { SpriteManager.FacingState = SpriteManager.FacingStates.Right; } //Damage //rigidBody.Mass = (CurrentHealth / 200) + .5F; //Spawn blood playerParticleManager.SpawnBlood(gameSession.gameMap); //Spawn damage indicator playerParticleManager.SpawnDamageNotifier(-colliderInfo.CollisionDamage, gameSession.gameMap); } else { RectangleF boundaryRectangle = rigidBody.CollisionPolygon.BoundaryRectangle; PlayerParticleManager PPM = new PlayerParticleManager(PlayerTexturePack, new RotationRectangle(new RectangleF(collidedInfo.colliderPosition.X - (boundaryRectangle.Width / 2), collidedInfo.colliderPosition.Y - (boundaryRectangle.Height / 2), boundaryRectangle.Width, boundaryRectangle.Height)), drawDimensions); PPM.SpawnBlood(gameMap); PPM.SpawnDamageNotifier(colliderInfo.CollisionDamage, gameMap); } }
/// <summary> /// Sent on entity collision. /// </summary> protected virtual void OnCollision(ColliderInfo source, ColliderInfo target, Vector3 hitPos, Vector3 contactNormal, float penetration, float radius) { }
static public void RemoveOverlap(Transform t, MeshCombineJobManager.MeshCombineJob meshCombineJob, MeshCache.SubMeshCache newMeshCache, ref byte[] vertexIsInsideCollider) { if (vertexIsInsideCollider == null) { vertexIsInsideCollider = new byte[65534]; } int overlapLayerMask = meshCombineJob.meshCombiner.overlapLayerMask; int voxelizeLayer = meshCombineJob.meshCombiner.voxelizeLayer; int voxelizeLayerMask = 1 << voxelizeLayer; int lodGroupLayer = meshCombineJob.meshCombiner.lodGroupLayer; int lodGroupLayerMask = 1 << lodGroupLayer; int lodLevel = meshCombineJob.meshObjectsHolder.lodLevel; Vector3 cellOffset = meshCombineJob.position; CreateOverlapColliders.newT.position = -cellOffset; t.parent.position -= cellOffset; #if !UNITY_2017 if (!Physics.autoSyncTransforms) { Physics.SyncTransforms(); } #endif CreateOverlapColliders.EnableLodLevelCollider(lodLevel, lodGroupLayer); Vector3[] newVertices = newMeshCache.vertices; int[] newTriangles = newMeshCache.triangles; FastList <MeshObject> meshObjects = meshCombineJob.meshObjectsHolder.meshObjects; int startIndex = meshCombineJob.startIndex; int endIndex = meshCombineJob.endIndex; bool queriesHitBackfaces = Physics.queriesHitBackfaces; Physics.queriesHitBackfaces = true; toCombineGos.Clear(); for (int i = startIndex; i < endIndex; i++) { toCombineGos.Add(meshObjects.items[i].cachedGO.go); } for (int a = startIndex; a < endIndex; a++) { MeshObject meshObject = meshObjects.items[a]; CachedGameObject cachedGO = meshObject.cachedGO; GameObject go; CreateOverlapColliders.lookupOrigCollider.TryGetValue(cachedGO.go, out go); int startTriangleIndex = meshObject.startNewTriangleIndex; int endTriangleIndex = meshObject.newTriangleCount + startTriangleIndex; Bounds bounds = cachedGO.mr.bounds; bounds.center -= cellOffset; int oldLayer = 0; if (go) { oldLayer = go.layer; go.layer = voxelizeLayer; } colliders.SetCount(Physics.OverlapBoxNonAlloc(bounds.center, bounds.extents, colliders.items, Quaternion.identity, overlapLayerMask)); if (go) { go.layer = oldLayer; } // Debug.Log("collider Count " + colliders.Count); if (colliders.Count == 0) { continue; } collidersInfo.SetCount(colliders.Count); for (int i = 0; i < colliders.Count; i++) { GameObject colliderGo = colliders.items[i].gameObject; collidersInfo.items[i] = new ColliderInfo() { layer = colliderGo.layer, go = colliderGo }; colliderGo.layer = voxelizeLayer; } // Debug.Log("start " + startTriangleIndex + " end " + endTriangleIndex); for (int i = startTriangleIndex; i < endTriangleIndex; i += 3) { int vertIndexA = newTriangles[i]; if (vertIndexA == -1) { continue; } byte isInsideVoxel = vertexIsInsideCollider[vertIndexA]; if (isInsideVoxel != outsideVoxel) { tri.a = t.TransformPoint(newVertices[vertIndexA]); hitInfos.SetCount(Physics.RaycastNonAlloc(tri.a, Vector3.up, hitInfos.items, Mathf.Infinity, voxelizeLayerMask)); if (!AnythingInside()) { vertexIsInsideCollider[vertIndexA] = outsideVoxel; continue; } tri.b = t.TransformPoint(newVertices[newTriangles[i + 1]]); tri.c = t.TransformPoint(newVertices[newTriangles[i + 2]]); if (LinecastAll(tri.a, tri.b, voxelizeLayerMask) && IntersectAny()) { continue; } if (LinecastAll(tri.b, tri.c, voxelizeLayerMask) && IntersectAny()) { continue; } if (LinecastAll(tri.c, tri.a, voxelizeLayerMask) && IntersectAny()) { continue; } if (LinecastAll(tri.a, (tri.b + tri.c) * 0.5f, voxelizeLayerMask) && IntersectAny()) { continue; } if (LinecastAll(tri.b, (tri.c + tri.a) * 0.5f, voxelizeLayerMask) && IntersectAny()) { continue; } if (LinecastAll(tri.c, (tri.a + tri.b) * 0.5f, voxelizeLayerMask) && IntersectAny()) { continue; } //tri.Calc(); //Vector3 origin = tri.a + (tri.dirAb / 2) + ((tri.c - tri.h1) / 2); //if (Physics.CheckBox(origin, new Vector3(0.05f, tri.h, tri.ab) / 2, Quaternion.LookRotation(tri.dirAb, tri.dirAc), voxelizeLayerMask)) //{ // colliderGO.layer = oldLayer; // continue; //} if (CreateOverlapColliders.foundLodGroup && AreAllHitInfosALodGroup() && !IsOneColliderGOInToCombineGos() && !CheckAnyInsideOfLodGroups(lodGroupLayerMask, lodLevel)) { continue; } meshCombineJob.trianglesRemoved += 3; newTriangles[i] = -1; } } for (int i = 0; i < colliders.Count; i++) { ColliderInfo colliderInfo = collidersInfo.items[i]; colliderInfo.go.layer = colliderInfo.layer; } } Array.Clear(vertexIsInsideCollider, 0, newVertices.Length); // Debug.Log("Removed " + meshCombineJob.trianglesRemoved); newMeshCache.triangles = newTriangles; Physics.queriesHitBackfaces = queriesHitBackfaces; t.parent.position += cellOffset; }
// Update is called once per frame void FixedUpdate() { Collider[] hits = Physics.OverlapSphere(centerOfSphere.position, radius, checkLayers); if (hits.Length != 0) { foreach (Collider c in hits) { if (lastTreeCollisions.Select(items => items.c).Contains(c)) { break; } if (c.gameObject.layer == LayerMask.NameToLayer("PoI")) { PoI parent = GlobalMethods.FindParentWithTag(c.gameObject, "PoI")?.GetComponent <PoI>(); if (parent is FallenBigTree fallen) { BrokenTreePart brokenPart = c.gameObject.GetComponent <BrokenTreePart>(); if (brokenPart.Alive) { fallen.DestroyPart(brokenPart); ColliderInfo cInfo = new ColliderInfo(); cInfo.Setup(c, TypeOfParent.P_POI, parent); lastTreeCollisions.Add(cInfo); } } } else if (c.gameObject.layer == LayerMask.NameToLayer("Interactable")) { Interactable parent = GlobalMethods.FindParentWithTag(c.gameObject, "TreeLogic")?.GetComponent <Interactable>(); if (parent is Trees tree) { if (c.name.EndsWith("0") && !tree.lDis.isDissolving) { tree.Controller.handleTreeDestroy(tree); ColliderInfo cInfo = new ColliderInfo(); cInfo.Setup(c, TypeOfParent.P_INT, parent); lastTreeCollisions.Add(cInfo); } } } } Collider[] tempCopy = lastTreeCollisions.Select(item => item.c).ToArray(); for (int i = 0; i < tempCopy.Length; i++) { Collider c = tempCopy[i]; Collider found = hits.FirstOrDefault(pC => pC.name.Equals(c.name)); if (found == null) { lastTreeCollisions.RemoveAt(i); } } /* * foreach(Collider c in tempCopy) * { * Collider found = hits.FirstOrDefault(pC => pC.name.Equals(c.name)); * if(found == null) * { * lastTreeCollisions.Remove(c); * } * } */ } else { lastTreeCollisions.Clear(); } }
public virtual void Init() { vUnitColliderInfo = gameObject.GetComponent<ColliderInfo>(); mTransform = transform; }