bool CheckCapsuleAtPos(Vector3 pos, Color debugColor, Vector3 fromPos) { Vector3 spawnPosReal = CollisionUtils.GetGroundedPos(pos); Vector3 A = spawnPosReal + Vector3.up * (m_Radius + 0.05f); // take it little bit over the ground Vector3 B = spawnPosReal + Vector3.up * (m_Height - m_Radius); int Default = 1 << LayerMask.NameToLayer("Default"); int PhysicsMetal = 1 << LayerMask.NameToLayer("PhysicsMetal"); if (Physics.CheckCapsule(A, B, m_Radius, Default | PhysicsMetal)) { DebugDraw.DisplayTime = 1; //DebugDraw.Diamond( debugColor, 0.03f, A ); //DebugDraw.LineOriented( debugColor, A, B, 0.05f ); DebugDraw.Capsule(debugColor, m_Radius, A, B); //if( fromPos != null ) { DebugDraw.LineOriented(Color.magenta, fromPos, A); DebugDraw.LineOriented(Color.magenta, fromPos, B); DebugDraw.LineOriented(Color.magenta, fromPos, 0.5f * (A + B)); } return(false); } return(true); }
protected override void OnUpdate() { for (int i = 0, c = Group.capsules.Length; i < c; i++) { var capsule = Group.capsules[i]; var v = capsule.pB - capsule.pA; var center = capsule.pA + v * 0.5f; DebugDraw.Capsule(center, v.normalized, capsule.radius, v.magnitude + capsule.radius * 2, capsule.color); } }
protected override void OnUpdate() { var capsuleArray = Group.GetComponentArray <CapsulePrimitive>(); for (int i = 0, c = capsuleArray.Length; i < c; i++) { var capsule = capsuleArray[i]; var v = capsule.pB - capsule.pA; var center = capsule.pA + v * 0.5f; DebugDraw.Capsule(center, v.normalized, capsule.radius, v.magnitude + capsule.radius * 2, capsule.color); } }
public void DrawStateAtIndex(int stateIndex, HitCollisionHistory colliderCollection, Color color, float duration) { for (var i = 0; i < colliderCollection.colliders.Length; i++) { var bonePosition = buffer[stateIndex].bonePositions[i]; var boneRotation = buffer[stateIndex].boneRotations[i]; var worldPos = boneRotation * colliderCollection.colliders[i].localPosition + bonePosition; var worldRot = boneRotation * colliderCollection.colliders[i].localRotation; var capsuleCollider = colliderCollection.colliders[i].collider as CapsuleCollider; if (capsuleCollider != null) { DebugDraw.Capsule(worldPos, worldRot * Vector3.up, capsuleCollider.radius, capsuleCollider.height, color, duration); } } }
//collide camera and place it to the best position void CollideCamera5() { // #if CAMERA_DEBUG_DRAW Color col; #endif Transform desiredTransform = CameraBehaviour.GetDesiredCameraTransform(); if (desiredTransform) { Vector3 desiredPosition = desiredTransform.position; Quaternion desiredRotation = desiredTransform.rotation; float dif = (desiredPosition - PrevPos).sqrMagnitude; #if !CAMERA_DEBUG_DRAW //disable the optimization when Debug Draw is on //exit if the camera didn't move or rotate if (dif < 0.0001f && Mathf.Approximately(PrevRot.x, desiredRotation.x) && Mathf.Approximately(PrevRot.y, desiredRotation.y) && Mathf.Approximately(PrevRot.z, desiredRotation.z) && Mathf.Approximately(PrevRot.w, desiredRotation.w)) { return; } #endif //blend the transform (this is useful especially when the CameraState changes or when the camera moves very fast) if (dif > 0.1f) { desiredPosition = Vector3.Lerp(PrevPos, desiredPosition, Time.deltaTime * 20); desiredRotation = Quaternion.Slerp(PrevRot, desiredRotation, Time.deltaTime * 20); } PrevPos = desiredPosition; PrevRot = desiredRotation; Vector3 FinalPos; //pokud je jiny CameraState nez CameraState3RD, tak muzeme nasledujici testy preskocit a jen nastavit CameraTransform.position a CameraTransform.rotation a zavolat UpdateLocalPlayerInstance(); // if ( (CameraBehaviour.State is CameraState3RD) || (CameraBehaviour.State is CameraStateCover) || (CameraBehaviour.State is CameraStateDeath) ) { LayerMask mask = ObjectLayerMask.Default | ObjectLayerMask.PhysicsMetal; //~( ObjectLayerMask.Ragdoll | ObjectLayerMask.IgnoreRayCast | ObjectLayerMask.PhysicBody ); const float minNear = 0.02f; //0.05f still penetrates walls while rolling const float minRadius = 0.12f; //0.1f const float maxRadius = 0.3f; //with 0.5f the camera collides too often when player runs close to obstacles bool IsRolling = CameraBehaviour.Owner.PlayerComponent.IsRolling; bool IsAlive = CameraBehaviour.Owner.IsAlive; float radius = IsRolling ? minRadius : maxRadius; //in dodge, use minRadius for collisions //for testing collision between Head and TargetPos ("CameraTargetDir" node) Vector3 HeadPos = CameraBehaviour.Owner.EyePosition; Vector3 TargetPos = CameraBehaviour.CameraOrigin.position; Vector3 headDir = TargetPos - HeadPos; //shift the HeadPos to not allow the camera to move into player's head HeadPos += headDir * 0.5f; //middle point between head and target headDir = TargetPos - HeadPos; float headLength = headDir.magnitude; RaycastHit headHit; #if CAMERA_DEBUG_DRAW DebugDraw.Line(Color.magenta, HeadPos, TargetPos + headDir.normalized * radius); //c DebugDraw.Diamond(Color.magenta, 0.03f, TargetPos); DebugDraw.Diamond(Color.green, 0.03f, desiredPosition); #endif //check whether the TargetPos is behind collision or not (it is controlled by animation and usually is outside the player's capsule collider) //this happens when players 'shoulder' (i.e. the "CameraTargetDir") gets behind a wall if (Physics.Raycast(HeadPos, headDir, out headHit, headLength + radius, mask)) { float m = Mathf.Max(0, headHit.distance - radius); TargetPos = HeadPos + headDir.normalized * m; //move the TargetPos along the line to a safe place if (headHit.distance < radius) { radius = Mathf.Max(minRadius, headHit.distance - 0.001f); //change the radius based on the collision distance } #if CAMERA_DEBUG_DRAW DebugDraw.Diamond(Color.cyan, 0.03f, headHit.point); DebugDraw.Diamond(Color.white, 0.03f, TargetPos); //new TargetPos DebugDraw.Line(Color.green, headHit.point, headHit.point + headHit.normal * (radius + 0.01f)); //b DebugDraw.Line(Color.yellow, headHit.point + headHit.normal * (radius + 0.01f), TargetPos); #endif } // Vector3 dir = desiredPosition - TargetPos; Vector3 dirN = dir.normalized; float length = dir.magnitude; float q, dist; const float safeDist = maxRadius + 0.1f; //shift the capsule in front of the TargetPos a little //do the sphere (capsule) collision with scene RaycastHit[] hits = Physics.SphereCastAll(TargetPos - dirN * safeDist, radius, dirN, length + safeDist, mask); //sort by distance if (hits.Length > 1) { System.Array.Sort(hits, CollisionUtils.CompareHits); } // FinalPos = desiredPosition; dist = length; //default position at the desiredPosition if we will not collide MainCamera.nearClipPlane = Mathf.Max(0.2f, radius * 0.5f); //radius * 0.5f; //was 0.3f; foreach (RaycastHit hit in hits) { if (hit.collider.gameObject.layer == InteractionObject.UseLayer) { continue; } if (hit.collider.isTrigger) { continue; } if (hit.collider == IgnoredCollider) { continue; } // FinalPos = hit.point + hit.normal * minRadius; //was 0.3f; changed to 0.1f to help fix the camera-player intersection (when player was running backwards against wall) dist = Mathf.Min(length, hit.distance + radius - safeDist - minRadius); if (dist < 0) //can become < 0 due to safeDist { dist = 0; } // FinalPos = TargetPos + dirN * q; MainCamera.nearClipPlane = (IsRolling || !IsAlive) ? minNear : 0.2f; //0.02f; //was 0.05f; the new value needs testing on devices (check z-fight) #if CAMERA_DEBUG_DRAW col = Color.grey; col.a = 0.5f; Debug.DrawLine(desiredPosition, TargetPos, col, 0.5f); DebugDraw.Diamond(Color.red, 0.03f, hit.point); col = Color.gray; col.a = 0.5f; DebugDraw.Capsule(col, radius, TargetPos - dirN * safeDist, TargetPos + dirN * length); #endif break; //need to care just about the nearest valid hit } // float ratio = (Mathf.Abs(PrevDist - dist) / length) + (1 - (radius - minRadius) / maxRadius); if (PrevDist < dist) //we're returning back - do it slower { ratio *= 0.5f; } float speed = Mathf.Clamp(ratio, 0.2f, 1.0f) * 25; //change the blend speed based on the distance between actual and computed distance (position) q = Mathf.Lerp(PrevDist, dist, Time.deltaTime * speed); //smoothly blend between previous and current position // if ( Mathf.Abs(PrevDist - dist) > 0.01f ) // Debug.Log ("radius=" + radius + ", dist=" + dist + ", PrevDist=" + PrevDist + ", ratio=" + ratio + ", q=" + q + ", speed=" + speed); PrevDist = q; #if CAMERA_DEBUG_DRAW DebugDraw.Diamond(Color.yellow, 0.03f, TargetPos + dirN * dist); //where we need to be (we're interpolating to this pos) #endif //set Final Position FinalPos = TargetPos + dirN * q; } // else // { // FinalPos = desiredPosition; // } //set Final Position CameraTransform.position = FinalPos; //CameraTransform.rotation = Quaternion.Lerp(CameraTransform.rotation, desiredRotation, 15.0f * Time.deltaTime); CameraTransform.rotation = desiredRotation; // #if CAMERA_DEBUG_DRAW col = Color.yellow; col.a = 0.5f; DebugDraw.Diamond(col, 0.03f, FinalPos); #endif UpdateLocalPlayerInstance(); } }