public EventData Set(RaycastHit?targetHit, bool isValid, HeapAllocationFreeReadOnlyList <Vector3> points) { HitData = targetHit; IsValid = isValid; Points = points; return(this); }
/// <summary> /// Applies each (or the first active) source data to every (or only active) targets. /// </summary> /// <param name="sources">The sources to apply the data from.</param> /// <param name="targets">The targets to apply the data to.</param> protected virtual void ApplySourcesToTargets(HeapAllocationFreeReadOnlyList <TSource> sources, HeapAllocationFreeReadOnlyList <TTarget> targets) { for (int sourceIndex = 0; sourceIndex < sources.Count; sourceIndex++) { TSource currentSource = sources[sourceIndex]; if (!IsSourceValid(currentSource)) { continue; } for (int targetIndex = 0; targetIndex < targets.Count; targetIndex++) { TTarget currentTarget = targets[targetIndex]; if (!IsTargetValid(currentTarget)) { continue; } SetCurrentIndices(sourceIndex, targetIndex); ApplySourceToTarget(currentSource, currentTarget); } ActiveSource = currentSource; if (CeaseAfterFirstSourceProcessed) { break; } } }
/// <summary> /// Checks whether <see cref="Character"/> is grounded. /// </summary> /// <remarks> /// <see cref="CharacterController.isGrounded"/> isn't accurate so this method does an additional check using <see cref="Physics"/>. /// </remarks> /// <returns>Whether <see cref="Character"/> is grounded.</returns> protected virtual bool CheckIfCharacterControllerIsGrounded() { if (Character.isGrounded) { return(true); } HeapAllocationFreeReadOnlyList <Collider> hitColliders = PhysicsCast.OverlapSphereAll( null, Character.transform.position + (Vector3.up * (Character.radius - Character.skinWidth - 0.001f)), Character.radius, 1 << Character.gameObject.layer); foreach (Collider hitCollider in hitColliders) { if (hitCollider != Character && hitCollider != RigidbodyCollider && !ignoredColliders.Contains(hitCollider) && !Physics.GetIgnoreLayerCollision( hitCollider.gameObject.layer, Character.gameObject.layer) && !Physics.GetIgnoreLayerCollision(hitCollider.gameObject.layer, PhysicsBody.gameObject.layer)) { return(true); } } return(false); }
/// <summary> /// Applies each (or the first active) source data to every (or only active) targets. /// </summary> /// <param name="sources">The sources to apply the data from.</param> /// <param name="targets">The targets to apply the data to.</param> protected virtual void ApplySourcesToTargets(HeapAllocationFreeReadOnlyList <TSource> sources, HeapAllocationFreeReadOnlyList <TTarget> targets) { bool foundValidSource = false; for (int sourceIndex = 0; sourceIndex < sources.Count; sourceIndex++) { TSource currentSource = sources[sourceIndex]; if (!IsSourceValid(currentSource)) { continue; } for (int targetIndex = 0; targetIndex < targets.Count; targetIndex++) { TTarget currentTarget = targets[targetIndex]; if (!IsTargetValid(currentTarget)) { continue; } SetCurrentIndices(sourceIndex, targetIndex); ApplySourceToTarget(currentSource, currentTarget); } if (!EqualityComparer <TSource> .Default.Equals(ActiveSource, currentSource)) { ActiveSourceChanging?.Invoke(currentSource); } ActiveSource = currentSource; foundValidSource = true; if (CeaseAfterFirstSourceProcessed) { break; } } if (!foundValidSource && !EqualityComparer <TSource> .Default.Equals(ActiveSource, default)) { ActiveSource = default; ActiveSourceChanging?.Invoke(default);
/// <summary> /// Casts a ray from the <see cref="Source"/> origin location towards the <see cref="Target"/> destination location and determines whether the raycast is blocked by another <see cref="Collider"/>. /// </summary> public virtual void Process() { Vector3 sourcePosition = Source.transform.position; Vector3 difference = Target.transform.position - sourcePosition; Ray ray = new Ray(sourcePosition, difference); HeapAllocationFreeReadOnlyList <RaycastHit> raycastHits = PhysicsCast.RaycastAll( PhysicsCast, ray, difference.magnitude, Physics.IgnoreRaycastLayer); bool isObscured = false; foreach (RaycastHit hit in raycastHits) { GameObject hitGameObject = hit.transform.gameObject; if (hitGameObject != Source && hitGameObject != Target) { isObscured = true; break; } } if (isObscured == wasPreviouslyObscured) { return; } wasPreviouslyObscured = isObscured; if (isObscured) { TargetObscured?.Invoke(raycastHits); } else { TargetUnobscured?.Invoke(); } }
public void GeneratePoints() { const int curvePoints = 10; Vector3 origin = Vector3.zero; Vector3 forward = Vector3.forward * 4; Vector3 down = (Vector3.forward * 4) + (Vector3.down * 2); Vector3[] controlPoints = new Vector3[] { origin, forward, down, down }; Vector3[] expectedResults = new Vector3[] { new Vector3(0f, 0f, 0f), new Vector3(0f, -0.1f, 1.2f), new Vector3(0f, -0.3f, 2.1f), new Vector3(0f, -0.5f, 2.8f), new Vector3(0f, -0.8f, 3.3f), new Vector3(0f, -1.2f, 3.6f), new Vector3(0f, -1.5f, 3.9f), new Vector3(0f, -1.7f, 4f), new Vector3(0f, -1.9f, 4f), new Vector3(0f, -2f, 4f), }; HeapAllocationFreeReadOnlyList <Vector3> actualResults = BezierCurveGenerator.GeneratePoints(curvePoints, controlPoints); for (int index = 0; index < actualResults.Count; index++) { Assert.AreEqual(expectedResults[index].ToString(), actualResults[index].ToString(), "index " + index); } }