protected override bool DetectSetup() { if (hjCreated) { Bounds bounds = Utilities.GetBounds(transform, transform); switch (direction) { case LeverDirection.x: hj.anchor = (bounds.extents.y > bounds.extents.z) ? new Vector3(0, bounds.extents.y / transform.lossyScale.y, 0) : new Vector3(0, 0, bounds.extents.z / transform.lossyScale.z); break; case LeverDirection.y: hj.axis = new Vector3(0, 1, 0); hj.anchor = (bounds.extents.x > bounds.extents.z) ? new Vector3(bounds.extents.x / transform.lossyScale.x, 0, 0) : new Vector3(0, 0, bounds.extents.z / transform.lossyScale.z); break; case LeverDirection.z: hj.axis = new Vector3(0, 0, 1); hj.anchor = (bounds.extents.y > bounds.extents.x) ? new Vector3(0, bounds.extents.y / transform.lossyScale.y, 0) : new Vector3(bounds.extents.x / transform.lossyScale.x, 0); break; } hj.anchor *= -1; // subdirection detection not yet implemented } if (hj) { hj.useLimits = true; JointLimits limits = hj.limits; limits.min = minAngle; limits.max = maxAngle; hj.limits = limits; } return(true); }
private Direction DetectDirection() { Direction direction = Direction.autodetect; Bounds handleBounds = Utilities.GetBounds(handle.transform, transform); Bounds bodyBounds = Utilities.GetBounds(body.transform, transform); float lengthX = Mathf.Abs(handleBounds.center.x - (bodyBounds.center.x + bodyBounds.extents.x)); float lengthZ = Mathf.Abs(handleBounds.center.z - (bodyBounds.center.z + bodyBounds.extents.z)); float lengthNegX = Mathf.Abs(handleBounds.center.x - (bodyBounds.center.x - bodyBounds.extents.x)); float lengthNegZ = Mathf.Abs(handleBounds.center.z - (bodyBounds.center.z - bodyBounds.extents.z)); if (Utilities.IsLowest(lengthX, new float[] { lengthZ, lengthNegX, lengthNegZ })) { direction = Direction.x; } else if (Utilities.IsLowest(lengthNegX, new float[] { lengthX, lengthZ, lengthNegZ })) { direction = Direction.x; } else if (Utilities.IsLowest(lengthZ, new float[] { lengthX, lengthNegX, lengthNegZ })) { direction = Direction.z; } else if (Utilities.IsLowest(lengthNegZ, new float[] { lengthX, lengthZ, lengthNegX })) { direction = Direction.z; } return(direction); }
public override void OnDrawGizmos() { base.OnDrawGizmos(); if (!setupSuccessful) { return; } // show opening direction Bounds handleBounds = Utilities.GetBounds(getHandle().transform, getHandle().transform); float length = handleBounds.extents.y * ((handle) ? 5f : 1f); Vector3 point = handleBounds.center; switch (finalDirection) { case Direction.x: point -= transform.right.normalized * length * subDirection; break; case Direction.y: point -= transform.up.normalized * length * subDirection; break; case Direction.z: point -= transform.forward.normalized * length * subDirection; break; } Gizmos.DrawLine(handleBounds.center, point); Gizmos.DrawSphere(point, length / 8f); }
protected override void OnDrawGizmos() { base.OnDrawGizmos(); if (!enabled || !setupSuccessful) { return; } // show opening direction Bounds handleBounds = Utilities.GetBounds(handle.transform, handle.transform); float length = handleBounds.extents.y * 5f; Vector3 point = handleBounds.center + new Vector3(0, length, 0); switch (finalDirection) { case Direction.x: point += transform.right.normalized * (length / 2f) * subDirection; break; case Direction.y: point += transform.up.normalized * (length / 2f) * subDirection; break; case Direction.z: point += transform.forward.normalized * (length / 2f) * subDirection; break; } Gizmos.DrawLine(handleBounds.center + new Vector3(0, handleBounds.extents.y, 0), point); Gizmos.DrawSphere(point, length / 8f); }
private float CalculateValue() { Vector3 center = (direction == Direction.autodetect) ? Utilities.GetBounds(transform).center : transform.position; float dist1 = Vector3.Distance(finalMinPoint, center); float dist2 = Vector3.Distance(center, finalMaxPoint); return(Mathf.Round((min + Mathf.Clamp01(dist1 / (dist1 + dist2)) * (max - min)) / stepSize) * stepSize); }
private void OnDrawGizmosSelected() { if (highlightObject && !displayDropZoneInEditor) { var boxSize = Utilities.GetBounds(highlightObject.transform).size * 1.05f; Gizmos.color = Color.red; Gizmos.DrawWireCube(highlightObject.transform.position, boxSize); } }
private KnobDirection DetectDirection() { KnobDirection direction = KnobDirection.x; Bounds bounds = Utilities.GetBounds(transform); // shoot rays in all directions to learn about surroundings RaycastHit hitForward; RaycastHit hitBack; RaycastHit hitLeft; RaycastHit hitRight; RaycastHit hitUp; RaycastHit hitDown; Physics.Raycast(bounds.center, Vector3.forward, out hitForward, bounds.extents.z * MAX_AUTODETECT_KNOB_WIDTH, Physics.DefaultRaycastLayers, QueryTriggerInteraction.UseGlobal); Physics.Raycast(bounds.center, Vector3.back, out hitBack, bounds.extents.z * MAX_AUTODETECT_KNOB_WIDTH, Physics.DefaultRaycastLayers, QueryTriggerInteraction.UseGlobal); Physics.Raycast(bounds.center, Vector3.left, out hitLeft, bounds.extents.x * MAX_AUTODETECT_KNOB_WIDTH, Physics.DefaultRaycastLayers, QueryTriggerInteraction.UseGlobal); Physics.Raycast(bounds.center, Vector3.right, out hitRight, bounds.extents.x * MAX_AUTODETECT_KNOB_WIDTH, Physics.DefaultRaycastLayers, QueryTriggerInteraction.UseGlobal); Physics.Raycast(bounds.center, Vector3.up, out hitUp, bounds.extents.y * MAX_AUTODETECT_KNOB_WIDTH, Physics.DefaultRaycastLayers, QueryTriggerInteraction.UseGlobal); Physics.Raycast(bounds.center, Vector3.down, out hitDown, bounds.extents.y * MAX_AUTODETECT_KNOB_WIDTH, Physics.DefaultRaycastLayers, QueryTriggerInteraction.UseGlobal); // shortest valid ray wins float lengthX = (hitRight.collider != null) ? hitRight.distance : float.MaxValue; float lengthY = (hitDown.collider != null) ? hitDown.distance : float.MaxValue; float lengthZ = (hitBack.collider != null) ? hitBack.distance : float.MaxValue; float lengthNegX = (hitLeft.collider != null) ? hitLeft.distance : float.MaxValue; float lengthNegY = (hitUp.collider != null) ? hitUp.distance : float.MaxValue; float lengthNegZ = (hitForward.collider != null) ? hitForward.distance : float.MaxValue; // TODO: not yet the right decision strategy, works only partially if (Utilities.IsLowest(lengthX, new float[] { lengthY, lengthZ, lengthNegX, lengthNegY, lengthNegZ })) { direction = KnobDirection.z; } else if (Utilities.IsLowest(lengthY, new float[] { lengthX, lengthZ, lengthNegX, lengthNegY, lengthNegZ })) { direction = KnobDirection.y; } else if (Utilities.IsLowest(lengthZ, new float[] { lengthX, lengthY, lengthNegX, lengthNegY, lengthNegZ })) { direction = KnobDirection.x; } else if (Utilities.IsLowest(lengthNegX, new float[] { lengthX, lengthY, lengthZ, lengthNegY, lengthNegZ })) { direction = KnobDirection.z; } else if (Utilities.IsLowest(lengthNegY, new float[] { lengthX, lengthY, lengthZ, lengthNegX, lengthNegZ })) { direction = KnobDirection.y; } else if (Utilities.IsLowest(lengthNegZ, new float[] { lengthX, lengthY, lengthZ, lengthNegX, lengthNegY })) { direction = KnobDirection.x; } return(direction); }
public virtual void OnDrawGizmos() { bounds = Utilities.GetBounds(transform); Gizmos.color = (setupSuccessful) ? COLOR_OK : COLOR_ERROR; if (setupSuccessful) { Gizmos.DrawWireCube(bounds.center, bounds.extents * 2); } else { Gizmos.DrawCube(bounds.center, bounds.extents * 2.01f); // draw slightly bigger to eliminate flickering } }
private void OnCollisionEnter(Collision collision) { Bounds insideBounds = Utilities.GetBounds(inside, null, control.GetContent().transform); Bounds objBounds = Utilities.GetBounds(transform); if (objBounds.Intersects(insideBounds)) { transform.parent = control.GetContent().transform; } else { transform.parent = outside; } }
private bool DoDetectMinMax(Direction direction) { Bounds bounds = Utilities.GetBounds(transform); Vector3 v = Vector3.zero; float extents = 0; switch (direction) { case Direction.x: v = Vector3.left; extents = bounds.extents.x; break; case Direction.y: v = Vector3.down; extents = bounds.extents.y; break; case Direction.z: v = Vector3.forward; extents = bounds.extents.z; break; } RaycastHit hit1; RaycastHit hit2; Physics.Raycast(bounds.center, v, out hit1, extents * MAX_AUTODETECT_SLIDER_LENGTH, Physics.DefaultRaycastLayers, QueryTriggerInteraction.UseGlobal); Physics.Raycast(bounds.center, v * -1, out hit2, extents * MAX_AUTODETECT_SLIDER_LENGTH, Physics.DefaultRaycastLayers, QueryTriggerInteraction.UseGlobal); if (hit1.collider && hit2.collider) { finalMinPoint = hit1.point; finalMaxPoint = hit2.point; // subtract width of slider to reach all values finalMinPoint = finalMinPoint + (finalMaxPoint - finalMinPoint).normalized * extents; finalMaxPoint = finalMaxPoint - (finalMaxPoint - finalMinPoint).normalized * extents; return(true); } else { finalMinPoint = transform.position; finalMaxPoint = transform.position; } return(false); }
private void CreateTriggerVolume() { GameObject tvGo = new GameObject(name + "-Trigger"); tvGo.transform.SetParent(transform); tvGo.AddComponent <VRTK_ControllerRigidbodyActivator>(); // calculate bounding box Bounds bounds = Utilities.GetBounds(transform); bounds.Expand(bounds.size * 0.2f); tvGo.transform.position = bounds.center; BoxCollider bc = tvGo.AddComponent <BoxCollider>(); bc.isTrigger = true; bc.size = bounds.size; }
private Vector3 CalculateActivationPoint() { Bounds bounds = Utilities.GetBounds(transform, transform); Vector3 buttonDirection = Vector3.zero; float extents = 0; switch (finalDirection) { case Direction.x: buttonDirection = transform.right * -1; extents = bounds.extents.x; break; case Direction.negX: buttonDirection = transform.right; extents = bounds.extents.x; break; case Direction.y: buttonDirection = transform.up * -1; extents = bounds.extents.y; break; case Direction.negY: buttonDirection = transform.up; extents = bounds.extents.y; break; case Direction.z: buttonDirection = transform.forward * -1; extents = bounds.extents.z; break; case Direction.negZ: buttonDirection = transform.forward; extents = bounds.extents.z; break; } // subtract width of button return(bounds.center + buttonDirection * (extents + activationDistance)); }
protected virtual void OnDrawGizmos() { if (!enabled) { return; } bounds = Utilities.GetBounds(transform); Gizmos.color = (setupSuccessful) ? COLOR_OK : COLOR_ERROR; if (setupSuccessful) { Gizmos.DrawWireCube(bounds.center, bounds.size); } else { Gizmos.DrawCube(bounds.center, bounds.size * 1.01f); // draw slightly bigger to eliminate flickering } }
private Direction DetectDirection() { Direction direction = Direction.autodetect; if (doorHj && !doorHjCreated) { // use direction of hinge joint if (doorHj.axis == Vector3.right) { direction = Direction.x; } else if (doorHj.axis == Vector3.up) { direction = Direction.y; } else if (doorHj.axis == Vector3.forward) { direction = Direction.z; } } else { if (handles) { Bounds handleBounds = Utilities.GetBounds(handles.transform, transform); Bounds doorBounds = Utilities.GetBounds(getDoor().transform, transform, handles.transform); // handles determine direction, there are actually two directions possible depending on handle position, we'll just detect one of them for now, preference is y if ((handleBounds.center.y + handleBounds.extents.y) > (doorBounds.center.y + doorBounds.extents.y) || (handleBounds.center.y - handleBounds.extents.y) < (doorBounds.center.y - doorBounds.extents.y)) { direction = Direction.x; } else { direction = Direction.y; } } } return(direction); }
private Direction DetectDirection() { Direction direction = Direction.autodetect; if (handles) { Bounds handleBounds = Utilities.GetBounds(handles.transform, transform); Bounds doorBounds = Utilities.GetBounds(getDoor().transform, transform, handles.transform); // handles determine direction, there are actually two directions possible depending on handle position, we'll just detect one of them for now, preference is y if ((handleBounds.center.y + handleBounds.extents.y) > (doorBounds.center.y + doorBounds.extents.y) || (handleBounds.center.y - handleBounds.extents.y) < (doorBounds.center.y - doorBounds.extents.y)) { direction = Direction.x; } else { direction = Direction.y; } } return(direction); }
protected override bool DetectSetup() { finalDirection = (direction == Direction.autodetect) ? DetectDirection() : direction; if (finalDirection == Direction.autodetect) { return(false); } // determin sub-direction depending on handle Bounds handleBounds = Utilities.GetBounds(getHandle().transform, transform); Bounds bodyBounds = Utilities.GetBounds(getBody().transform, transform); switch (finalDirection) { case Direction.x: subDirection = (handleBounds.center.x > bodyBounds.center.x) ? -1 : 1; pullDistance = bodyBounds.extents.x; break; case Direction.y: subDirection = (handleBounds.center.y > bodyBounds.center.y) ? -1 : 1; pullDistance = bodyBounds.extents.y; break; case Direction.z: subDirection = (handleBounds.center.z > bodyBounds.center.z) ? -1 : 1; pullDistance = bodyBounds.extents.z; break; } if (body & handle) { // handle should be outside body hierarchy, otherwise anchor-by-bounds calculation is off if (handle.transform.IsChildOf(body.transform)) { return(false); } } if (cjCreated) { cj.xMotion = ConfigurableJointMotion.Locked; cj.yMotion = ConfigurableJointMotion.Locked; cj.zMotion = ConfigurableJointMotion.Locked; switch (finalDirection) { case Direction.x: cj.axis = Vector3.right; cj.xMotion = ConfigurableJointMotion.Limited; break; case Direction.y: cj.axis = Vector3.up; cj.yMotion = ConfigurableJointMotion.Limited; break; case Direction.z: cj.axis = Vector3.forward; cj.zMotion = ConfigurableJointMotion.Limited; break; } cj.anchor = cj.axis * (-subDirection * pullDistance); } if (cj) { cj.angularXMotion = ConfigurableJointMotion.Locked; cj.angularYMotion = ConfigurableJointMotion.Locked; cj.angularZMotion = ConfigurableJointMotion.Locked; pullDistance *= 1.8f; // don't let it pull out completely SoftJointLimit limit = cj.linearLimit; limit.limit = pullDistance; cj.linearLimit = limit; } if (cfCreated) { cf.force = getThirdDirection(cj.axis, cj.secondaryAxis) * subDirection * -50f; } return(true); }
private Vector3 GetForceVector() { return(-(activationPoint - Utilities.GetBounds(transform).center).normalized * buttonStrength); }
private Vector3 CalculateActivationDir() { Bounds bounds = Utilities.GetBounds(transform, transform); Bounds bounds2 = Utilities.GetBounds(transform); Vector3 buttonDirection = Vector3.zero; float extents = 0; switch (direction) { case ButtonDirection.x: case ButtonDirection.negX: if (Mathf.RoundToInt(Mathf.Abs(transform.right.x)) == 1) { buttonDirection = transform.right; extents = bounds.extents.x; } else if (Mathf.RoundToInt(Mathf.Abs(transform.up.x)) == 1) { buttonDirection = transform.up; extents = bounds.extents.y; } else if (Mathf.RoundToInt(Mathf.Abs(transform.forward.x)) == 1) { buttonDirection = transform.forward; extents = bounds.extents.z; } buttonDirection *= (direction == ButtonDirection.x) ? -1 : 1; break; case ButtonDirection.y: case ButtonDirection.negY: if (Mathf.RoundToInt(Mathf.Abs(transform.right.y)) == 1) { buttonDirection = transform.right; extents = bounds.extents.x; } else if (Mathf.RoundToInt(Mathf.Abs(transform.up.y)) == 1) { buttonDirection = transform.up; extents = bounds.extents.y; } else if (Mathf.RoundToInt(Mathf.Abs(transform.forward.y)) == 1) { buttonDirection = transform.forward; extents = bounds.extents.z; } buttonDirection *= (direction == ButtonDirection.y) ? -1 : 1; break; case ButtonDirection.z: case ButtonDirection.negZ: if (Mathf.RoundToInt(Mathf.Abs(transform.right.z)) == 1) { buttonDirection = transform.right; extents = bounds.extents.x; } else if (Mathf.RoundToInt(Mathf.Abs(transform.up.z)) == 1) { buttonDirection = transform.up; extents = bounds.extents.y; } else if (Mathf.RoundToInt(Mathf.Abs(transform.forward.z)) == 1) { buttonDirection = transform.forward; extents = bounds.extents.z; } buttonDirection *= (direction == ButtonDirection.z) ? -1 : 1; break; } // subtract width of button return(buttonDirection * (extents + activationDistance)); }
private ButtonDirection DetectDirection() { ButtonDirection direction = ButtonDirection.autodetect; Bounds bounds = Utilities.GetBounds(transform); // shoot rays from the center of the button to learn about surroundings RaycastHit hitForward; RaycastHit hitBack; RaycastHit hitLeft; RaycastHit hitRight; RaycastHit hitUp; RaycastHit hitDown; Physics.Raycast(bounds.center, Vector3.forward, out hitForward, bounds.extents.z * MAX_AUTODETECT_ACTIVATION_LENGTH, Physics.DefaultRaycastLayers, QueryTriggerInteraction.UseGlobal); Physics.Raycast(bounds.center, Vector3.back, out hitBack, bounds.extents.z * MAX_AUTODETECT_ACTIVATION_LENGTH, Physics.DefaultRaycastLayers, QueryTriggerInteraction.UseGlobal); Physics.Raycast(bounds.center, Vector3.left, out hitLeft, bounds.extents.x * MAX_AUTODETECT_ACTIVATION_LENGTH, Physics.DefaultRaycastLayers, QueryTriggerInteraction.UseGlobal); Physics.Raycast(bounds.center, Vector3.right, out hitRight, bounds.extents.x * MAX_AUTODETECT_ACTIVATION_LENGTH, Physics.DefaultRaycastLayers, QueryTriggerInteraction.UseGlobal); Physics.Raycast(bounds.center, Vector3.up, out hitUp, bounds.extents.y * MAX_AUTODETECT_ACTIVATION_LENGTH, Physics.DefaultRaycastLayers, QueryTriggerInteraction.UseGlobal); Physics.Raycast(bounds.center, Vector3.down, out hitDown, bounds.extents.y * MAX_AUTODETECT_ACTIVATION_LENGTH, Physics.DefaultRaycastLayers, QueryTriggerInteraction.UseGlobal); // shortest valid ray wins float lengthX = (hitRight.collider != null) ? hitRight.distance : float.MaxValue; float lengthY = (hitDown.collider != null) ? hitDown.distance : float.MaxValue; float lengthZ = (hitBack.collider != null) ? hitBack.distance : float.MaxValue; float lengthNegX = (hitLeft.collider != null) ? hitLeft.distance : float.MaxValue; float lengthNegY = (hitUp.collider != null) ? hitUp.distance : float.MaxValue; float lengthNegZ = (hitForward.collider != null) ? hitForward.distance : float.MaxValue; float extents = 0; Vector3 hitPoint = Vector3.zero; if (Utilities.IsLowest(lengthX, new float[] { lengthY, lengthZ, lengthNegX, lengthNegY, lengthNegZ })) { direction = ButtonDirection.negX; hitPoint = hitRight.point; extents = bounds.extents.x; } else if (Utilities.IsLowest(lengthY, new float[] { lengthX, lengthZ, lengthNegX, lengthNegY, lengthNegZ })) { direction = ButtonDirection.y; hitPoint = hitDown.point; extents = bounds.extents.y; } else if (Utilities.IsLowest(lengthZ, new float[] { lengthX, lengthY, lengthNegX, lengthNegY, lengthNegZ })) { direction = ButtonDirection.z; hitPoint = hitBack.point; extents = bounds.extents.z; } else if (Utilities.IsLowest(lengthNegX, new float[] { lengthX, lengthY, lengthZ, lengthNegY, lengthNegZ })) { direction = ButtonDirection.x; hitPoint = hitLeft.point; extents = bounds.extents.x; } else if (Utilities.IsLowest(lengthNegY, new float[] { lengthX, lengthY, lengthZ, lengthNegX, lengthNegZ })) { direction = ButtonDirection.negY; hitPoint = hitUp.point; extents = bounds.extents.y; } else if (Utilities.IsLowest(lengthNegZ, new float[] { lengthX, lengthY, lengthZ, lengthNegX, lengthNegY })) { direction = ButtonDirection.negZ; hitPoint = hitForward.point; extents = bounds.extents.z; } // determin activation distance activationDistance = (Vector3.Distance(hitPoint, bounds.center) - extents) * 0.95f; if (direction == ButtonDirection.autodetect || activationDistance < 0.001f) { // auto-detection was not possible or colliding with object already direction = ButtonDirection.autodetect; activationDistance = 0; } else { activationDir = hitPoint - bounds.center; } return(direction); }
protected override bool DetectSetup() { // detect axis doorHj = getDoor().GetComponent <HingeJoint>(); if (doorHj && !doorHjCreated) { direction = Direction.autodetect; } finalDirection = (direction == Direction.autodetect) ? DetectDirection() : direction; if (finalDirection == Direction.autodetect) { return(false); } if (doorHj && !doorHjCreated) { // if there is a hinge joint already it overrides axis selection direction = finalDirection; } // detect opening direction Bounds doorBounds = Utilities.GetBounds(getDoor().transform, transform); if (doorHj == null || doorHjCreated) { if (handles) { // determin sub-direction depending on handle location Bounds handleBounds = Utilities.GetBounds(handles.transform, transform); switch (finalDirection) { case Direction.x: if ((handleBounds.center.z + handleBounds.extents.z) > (doorBounds.center.z + doorBounds.extents.z) || (handleBounds.center.z - handleBounds.extents.z) < (doorBounds.center.z - doorBounds.extents.z)) { subDirection = (handleBounds.center.y > doorBounds.center.y) ? -1 : 1; secondaryDirection = Vector3.up; } else { subDirection = (handleBounds.center.z > doorBounds.center.z) ? -1 : 1; secondaryDirection = Vector3.forward; } break; case Direction.y: if ((handleBounds.center.z + handleBounds.extents.z) > (doorBounds.center.z + doorBounds.extents.z) || (handleBounds.center.z - handleBounds.extents.z) < (doorBounds.center.z - doorBounds.extents.z)) { subDirection = (handleBounds.center.x > doorBounds.center.x) ? -1 : 1; secondaryDirection = Vector3.right; } else { subDirection = (handleBounds.center.z > doorBounds.center.z) ? -1 : 1; secondaryDirection = Vector3.forward; } break; case Direction.z: if ((handleBounds.center.x + handleBounds.extents.x) > (doorBounds.center.x + doorBounds.extents.x) || (handleBounds.center.x - handleBounds.extents.x) < (doorBounds.center.x - doorBounds.extents.x)) { subDirection = (handleBounds.center.y > doorBounds.center.y) ? -1 : 1; secondaryDirection = Vector3.up; } else { subDirection = (handleBounds.center.x > doorBounds.center.x) ? -1 : 1; secondaryDirection = Vector3.right; } break; } } else { switch (finalDirection) { case Direction.x: secondaryDirection = (doorBounds.extents.y > doorBounds.extents.z) ? Vector3.up : Vector3.forward; break; case Direction.y: secondaryDirection = (doorBounds.extents.x > doorBounds.extents.z) ? Vector3.right : Vector3.forward; break; case Direction.z: secondaryDirection = (doorBounds.extents.y > doorBounds.extents.x) ? Vector3.up : Vector3.right; break; } // TODO: derive how to detect -1 subDirection = 1; } } else { // calculate directions from existing anchor Vector3 dir = doorBounds.center - doorHj.connectedAnchor; if (dir.x != 0) { secondaryDirection = Vector3.right; subDirection = dir.x <= 0 ? 1 : -1; } else if (dir.y != 0) { secondaryDirection = Vector3.up; subDirection = dir.y <= 0 ? 1 : -1; } else if (dir.z != 0) { secondaryDirection = Vector3.forward; subDirection = dir.z <= 0 ? 1 : -1; } } if (doorHjCreated) { float extents = 0; if (secondaryDirection == Vector3.right) { extents = doorBounds.extents.x / getDoor().transform.lossyScale.x; } else if (secondaryDirection == Vector3.up) { extents = doorBounds.extents.y / getDoor().transform.lossyScale.y; } else { extents = doorBounds.extents.z / getDoor().transform.lossyScale.z; } doorHj.anchor = secondaryDirection * subDirection * extents; doorHj.axis = Direction2Axis(finalDirection); } if (doorHj) { doorHj.useLimits = true; doorHj.enableCollision = true; JointLimits limits = doorHj.limits; limits.min = openInward ? -maxAngle : 0; limits.max = openOutward ? maxAngle : 0; limits.bounciness = 0; doorHj.limits = limits; } if (doorCfCreated) { doorCf.relativeForce = getThirdDirection(doorHj.axis, secondaryDirection) * subDirection * -50f; } return(true); }
protected override bool DetectSetup() { if (body == null || handle == null) { return(false); } finalDirection = (direction == Direction.autodetect) ? DetectDirection() : direction; if (finalDirection == Direction.autodetect) { return(false); } // determin sub-direction depending on handle Bounds handleBounds = Utilities.GetBounds(handle.transform, transform); Bounds bodyBounds = Utilities.GetBounds(body.transform, transform); switch (finalDirection) { case Direction.x: subDirection = (handleBounds.center.x > bodyBounds.center.x) ? -1 : 1; break; case Direction.z: subDirection = (handleBounds.center.z > bodyBounds.center.z) ? -1 : 1; break; } if (body & handle) { // handle should be outside body hierarchy, otherwise anchor-by-bounds calculation is off if (handle.transform.IsChildOf(body.transform)) { return(false); } } if (cjCreated && handle) { cj.xMotion = ConfigurableJointMotion.Locked; cj.yMotion = ConfigurableJointMotion.Locked; cj.zMotion = ConfigurableJointMotion.Locked; switch (finalDirection) { case Direction.x: cj.anchor = new Vector3(-subDirection * bodyBounds.extents.x, 0, 0); cj.axis = new Vector3(1, 0, 0); cj.xMotion = ConfigurableJointMotion.Limited; pullDistance = bodyBounds.extents.x; break; case Direction.z: cj.anchor = new Vector3(0, 0, -subDirection * bodyBounds.extents.z); cj.axis = new Vector3(0, 0, 1); cj.xMotion = ConfigurableJointMotion.Limited; pullDistance = bodyBounds.extents.z; break; } pullDistance *= 1.8f; // don't let it pull out completely SoftJointLimit limit = cj.linearLimit; limit.limit = pullDistance; cj.linearLimit = limit; } return(true); }
private Direction DetectDirection() { Direction direction = Direction.autodetect; Bounds bounds = Utilities.GetBounds(transform); // shoot rays from the center of the slider, this means the center should be inside the frame to work properly RaycastHit hitForward; RaycastHit hitBack; RaycastHit hitLeft; RaycastHit hitRight; RaycastHit hitUp; RaycastHit hitDown; Physics.Raycast(bounds.center, Vector3.forward, out hitForward, bounds.extents.z * MAX_AUTODETECT_SLIDER_LENGTH, Physics.DefaultRaycastLayers, QueryTriggerInteraction.UseGlobal); Physics.Raycast(bounds.center, Vector3.back, out hitBack, bounds.extents.z * MAX_AUTODETECT_SLIDER_LENGTH, Physics.DefaultRaycastLayers, QueryTriggerInteraction.UseGlobal); Physics.Raycast(bounds.center, Vector3.left, out hitLeft, bounds.extents.x * MAX_AUTODETECT_SLIDER_LENGTH, Physics.DefaultRaycastLayers, QueryTriggerInteraction.UseGlobal); Physics.Raycast(bounds.center, Vector3.right, out hitRight, bounds.extents.x * MAX_AUTODETECT_SLIDER_LENGTH, Physics.DefaultRaycastLayers, QueryTriggerInteraction.UseGlobal); Physics.Raycast(bounds.center, Vector3.up, out hitUp, bounds.extents.y * MAX_AUTODETECT_SLIDER_LENGTH, Physics.DefaultRaycastLayers, QueryTriggerInteraction.UseGlobal); Physics.Raycast(bounds.center, Vector3.down, out hitDown, bounds.extents.y * MAX_AUTODETECT_SLIDER_LENGTH, Physics.DefaultRaycastLayers, QueryTriggerInteraction.UseGlobal); // shortest valid ray pair identifies first axis float lengthX = (hitLeft.collider != null && hitRight.collider != null) ? hitLeft.distance + hitRight.distance : float.MaxValue; float lengthY = (hitUp.collider != null && hitDown.collider != null) ? hitUp.distance + hitDown.distance : float.MaxValue; float lengthZ = (hitForward.collider != null && hitBack.collider != null) ? hitForward.distance + hitBack.distance : float.MaxValue; if (lengthX < lengthY & lengthX < lengthZ) { if (lengthY < lengthZ) { direction = Direction.y; } else if (lengthZ < lengthY) { direction = Direction.z; } else { // onset direction = Direction.x; } } if (lengthY < lengthX & lengthY < lengthZ) { if (lengthX < lengthZ) { direction = Direction.x; } else if (lengthZ < lengthX) { direction = Direction.z; } else { // onset direction = Direction.y; } } if (lengthZ < lengthX & lengthZ < lengthY) { if (lengthX < lengthY) { direction = Direction.x; } else if (lengthY < lengthX) { direction = Direction.y; } else { // onset direction = Direction.z; } } if (direction != Direction.autodetect) { if (!DoDetectMinMax(direction)) { direction = Direction.autodetect; } } else { finalMinPoint = transform.position; finalMaxPoint = transform.position; } return(direction); }
protected override bool DetectSetup() { if (lid == null || body == null) { return(false); } finalDirection = (direction == Direction.autodetect) ? DetectDirection() : direction; if (finalDirection == Direction.autodetect) { return(false); } Bounds lidBounds = Utilities.GetBounds(lid.transform, transform); // determin sub-direction depending on handle if (handle) { Bounds handleBounds = Utilities.GetBounds(handle.transform, transform); switch (finalDirection) { case Direction.x: subDirection = (handleBounds.center.x > lidBounds.center.x) ? -1 : 1; break; case Direction.y: subDirection = (handleBounds.center.y > lidBounds.center.y) ? -1 : 1; break; case Direction.z: subDirection = (handleBounds.center.z > lidBounds.center.z) ? -1 : 1; break; } // handle should be outside lid hierarchy, otherwise anchor-by-bounds calculation is off if (handle.transform.IsChildOf(lid.transform)) { return(false); } } else { subDirection = -1; } if (lidHjCreated) { lidHj.useLimits = true; lidHj.enableCollision = true; JointLimits limits = lidHj.limits; switch (finalDirection) { case Direction.x: lidHj.anchor = new Vector3(subDirection * lidBounds.extents.x, 0, 0); lidHj.axis = new Vector3(0, 0, 1); if (subDirection > 0) { limits.min = -maxAngle; limits.max = minAngle; } else { limits.min = minAngle; limits.max = maxAngle; } break; case Direction.y: lidHj.anchor = new Vector3(0, subDirection * lidBounds.extents.y, 0); lidHj.axis = new Vector3(0, 1, 0); if (subDirection > 0) { limits.min = -maxAngle; limits.max = minAngle; } else { limits.min = minAngle; limits.max = maxAngle; } break; case Direction.z: lidHj.anchor = new Vector3(0, 0, subDirection * lidBounds.extents.z); lidHj.axis = new Vector3(1, 0, 0); if (subDirection < 0) { limits.min = -maxAngle; limits.max = minAngle; } else { limits.min = minAngle; limits.max = maxAngle; } break; } lidHj.limits = limits; } return(true); }
protected override void OnDrawGizmos() { base.OnDrawGizmos(); if (!enabled || !setupSuccessful) { return; } // show opening direction Bounds bounds; float length; if (handles) { bounds = Utilities.GetBounds(handles.transform, handles.transform); length = 5f; } else { bounds = Utilities.GetBounds(getDoor().transform, getDoor().transform); length = 1f; } Vector3 dir = Vector3.zero; Vector3 dir2 = Vector3.zero; bool invertGizmos = false; switch (finalDirection) { case Direction.x: if (secondaryDirection == Vector3.up) { dir = transform.forward.normalized; dir2 = transform.up.normalized; length *= bounds.extents.y; invertGizmos = true; } else { dir = transform.up.normalized; dir2 = transform.forward.normalized; length *= bounds.extents.z; } break; case Direction.y: if (secondaryDirection == Vector3.right) { dir = transform.forward.normalized; dir2 = transform.right.normalized; length *= bounds.extents.x; } else { dir = transform.right.normalized; dir2 = transform.forward.normalized; length *= bounds.extents.z; invertGizmos = true; } break; case Direction.z: if (secondaryDirection == Vector3.up) { dir = transform.right.normalized; dir2 = transform.up.normalized; length *= bounds.extents.y; } else { dir = transform.up.normalized; dir2 = transform.right.normalized; length *= bounds.extents.z; invertGizmos = true; } break; } if ((!invertGizmos && openInward) || (invertGizmos && openOutward)) { Vector3 p1 = bounds.center; Vector3 p1end = p1 + dir2 * length * subDirection - dir * (length / 2f) * subDirection; Gizmos.DrawLine(p1, p1end); Gizmos.DrawSphere(p1end, length / 8f); } if ((!invertGizmos && openOutward) || (invertGizmos && openInward)) { Vector3 p2 = bounds.center; Vector3 p2end = p2 + dir2 * length * subDirection + dir * (length / 2f) * subDirection; Gizmos.DrawLine(p2, p2end); Gizmos.DrawSphere(p2end, length / 8f); } }
protected override bool DetectSetup() { finalDirection = (direction == Direction.autodetect) ? DetectDirection() : direction; if (finalDirection == Direction.autodetect) { return(false); } Bounds doorBounds = Utilities.GetBounds(getDoor().transform, transform); if (handles) { // determin sub-direction depending on handle location Bounds handleBounds = Utilities.GetBounds(handles.transform, transform); switch (finalDirection) { case Direction.x: if ((handleBounds.center.z + handleBounds.extents.z) > (doorBounds.center.z + doorBounds.extents.z) || (handleBounds.center.z - handleBounds.extents.z) < (doorBounds.center.z - doorBounds.extents.z)) { subDirection = (handleBounds.center.y > doorBounds.center.y) ? -1 : 1; secondaryDirection = Vector3.up; } else { subDirection = (handleBounds.center.z > doorBounds.center.z) ? -1 : 1; secondaryDirection = Vector3.forward; } break; case Direction.y: if ((handleBounds.center.z + handleBounds.extents.z) > (doorBounds.center.z + doorBounds.extents.z) || (handleBounds.center.z - handleBounds.extents.z) < (doorBounds.center.z - doorBounds.extents.z)) { subDirection = (handleBounds.center.x > doorBounds.center.x) ? -1 : 1; secondaryDirection = Vector3.right; } else { subDirection = (handleBounds.center.z > doorBounds.center.z) ? -1 : 1; secondaryDirection = Vector3.forward; } break; case Direction.z: if ((handleBounds.center.x + handleBounds.extents.x) > (doorBounds.center.x + doorBounds.extents.x) || (handleBounds.center.x - handleBounds.extents.x) < (doorBounds.center.x - doorBounds.extents.x)) { subDirection = (handleBounds.center.y > doorBounds.center.y) ? -1 : 1; secondaryDirection = Vector3.up; } else { subDirection = (handleBounds.center.x > doorBounds.center.x) ? -1 : 1; secondaryDirection = Vector3.right; } break; } } else { switch (finalDirection) { case Direction.x: secondaryDirection = (doorBounds.extents.y > doorBounds.extents.z) ? Vector3.up : Vector3.forward; break; case Direction.y: secondaryDirection = (doorBounds.extents.x > doorBounds.extents.z) ? Vector3.right : Vector3.forward; break; case Direction.z: secondaryDirection = (doorBounds.extents.y > doorBounds.extents.x) ? Vector3.up : Vector3.right; break; } subDirection = 1; } if (doorHjCreated) { float extents = 0; if (secondaryDirection == Vector3.right) { extents = doorBounds.extents.x / getDoor().transform.lossyScale.x; } else if (secondaryDirection == Vector3.up) { extents = doorBounds.extents.y / getDoor().transform.lossyScale.y; } else { extents = doorBounds.extents.z / getDoor().transform.lossyScale.z; } doorHj.anchor = secondaryDirection * subDirection * extents; switch (finalDirection) { case Direction.x: doorHj.axis = new Vector3(1, 0, 0); break; case Direction.y: doorHj.axis = new Vector3(0, 1, 0); break; case Direction.z: doorHj.axis = new Vector3(0, 0, 1); break; } } if (doorHj) { doorHj.useLimits = true; doorHj.enableCollision = true; JointLimits limits = doorHj.limits; limits.min = openInward ? -maxAngle : 0; limits.max = openOutward ? maxAngle : 0; limits.bounciness = 0; doorHj.limits = limits; } if (doorCfCreated) { doorCf.force = getThirdDirection(doorHj.axis, secondaryDirection) * subDirection * -50f; } return(true); }