igorciz777 Posted September 15, 2023 Share Posted September 15, 2023 I've been looking for an engine to migrate to from unity and so far unigine seems to be a really good choice but i cant quite get my head around intersections and all their different types I'm making a racing game and the tire/suspension script relies on a spherecast (used spherecast instead of a normal raycast for a smooth transition of the wheel on pointy terrain), here is a snippet of it if (Physics.SphereCast( new Vector3(transform.position.x, transform.position.y + radius, transform.position.z), radius, -transform.up, out wheelGroundHit, suspensionDistance + radius, roadLayer.value)) { ///////////// //////////// /////////// Vector3 position = transform.position - transform.up * wheelGroundHit.distance; compression = 1f - (wheelGroundHit.distance - radius) / suspensionDistance; camber = Vector3.Angle(Vector3.ProjectOnPlane(wheelGroundHit.normal.normalized, dummyWheel.transform.forward), dummyWheel.transform.up); toe = Vector3.Angle(Vector3.ProjectOnPlane(wheelGroundHit.normal.normalized, dummyWheel.transform.right), dummyWheel.transform.up); ////////////// ////////////// ////////////// visualWheel.transform.position = transform.position - transform.up * (wheelGroundHit.distance - radius); } What i cant quite recreate with intersections is setting a distance limit and reading the current ray length, basically anything that that uses wheelGroundHit in the script above would really appreciate some guidance, thanks in advance Link to comment
igorciz777 Posted September 17, 2023 Author Share Posted September 17, 2023 Alright so this is what i came up with so far: vec3 force = vec3.ZERO; WorldIntersectionNormal ray = new WorldIntersectionNormal(); wheelGroundHit = World.GetIntersection(node.WorldPosition, node.WorldPosition - node.GetWorldDirection(MathLib.AXIS.Z) * suspensionDistance, roadLayer, ray); if(wheelGroundHit){ float distance = (float)(node.WorldPosition - ray.Point).Length; isGrounded = true; wheelVelocity = (vec3)((node.WorldPosition - wheelPrevPosition) / Game.IFps); wheelPrevPosition = (vec3)node.WorldPosition; //wheelLongitudalVelocity = dummyWheel.transform.InverseTransformDirection(wheelVelocity).z; //wheelLateralVelocity = dummyWheel.transform.InverseTransformDirection(wheelVelocity).x; wheelLongitudalVelocity = (float)(dummyWheel.WorldPosition - wheelVelocity).Normalized.y; wheelLateralVelocity = (float)(dummyWheel.WorldPosition - wheelVelocity).Normalized.x; vec3 position = (vec3)(node.WorldPosition - node.GetWorldDirection(MathLib.AXIS.Z) * distance); compression = 1f - (distance - radius) / suspensionDistance; ///////////// ///////////// ///////////// visualWheel.WorldPosition = node.WorldPosition - node.GetWorldDirection(MathLib.AXIS.Z) * (distance - radius); } but the car in classic gamedev fashion flies into space at speed of sound, so im probably doing something wrong Link to comment
alexander Posted September 18, 2023 Share Posted September 18, 2023 Hi igorciz777, At first glance I don't see any issues. The code seems to be working. Are your wheels Objects? The car is a BodyRigid? There may be a collision between "visualWheel" (ObjectMeshSkinned?) and the body of your car (Object + BodyRigid). Unlike Unity, our physics can collide with meshes "as is", without shapes (colliders). Try to disable all Intersections, Collisions and Physics Intersections on all objects of your car: Best regards, Alexander Link to comment
igorciz777 Posted September 18, 2023 Author Share Posted September 18, 2023 (edited) None of the objects had those options selected but an useful thing to remember. Im thinking my initial understanding of Unity's InverseTransformDirection() function might be wrong, wheelLongitudal(Lateral)Velocity contribute to calculating forces applied to the wheel and those forces are in incredibly high numbers which is probably the cause of the car being launched Edit: im having trouble with using visualizer to draw the intersection, instead i moved an object to ray.Point and it seems that the intersection point is weirdly positioned to the right and behind of the wheel, it looks like the intersection goes at an angle rather than straight down, which i thought would happen with the endpoint (node.WorldPosition - (node.GetWorldDirection(MathLib.AXIS.Z) * suspensionDistance)) i set Edit2: Got the visualizer to work, the fault is still at the intersection code it seems. Edited September 18, 2023 by igorciz777 Link to comment
cash-metall Posted September 19, 2023 Share Posted September 19, 2023 Hi! The only option why you have an interaction and the visualizer looks sideways and not vertically is that your node is rotated in the world. Can you share a screenshot of node(and hierarhy) you added the component to? does this wheel spin? if you need strictly vertical - you can try using vec3.UP instead of node.GetWorldDirection(MathLib.AXIS.Z) It's just guesswork anyway. We need more context to understand what exactly is going wrong Link to comment
igorciz777 Posted September 19, 2023 Author Share Posted September 19, 2023 (edited) Multiplying node.GetWorldRotation() by vec3.UP did the job, the intersection now goes in the correct direction. The car still goes flying so i tried to port a simpler script that only does suspension without any tire forces but to no avail, car still launches up instantly Here is the unity script i tried to port github And here is the attempt public class Suspension : Component { [ShowInEditor] private Node vehicleNode; [ShowInEditor] private float wheelRadius = 0.5f; [ShowInEditor] private float suspensionDistanceConstant = 1f; [ShowInEditor] private float springConstant = 30000f; [ShowInEditor] private float damperConstant = 4000f; private BodyRigid vehicleBody; private float previousSuspensionDistance; private float currentSuspensionDistance; private float springVelocity; private float springForce; private float damperForce; private void Init(){ vehicleBody = vehicleNode.ObjectBodyRigid; Visualizer.Enabled = true; Unigine.Console.Run("show_visualizer 1"); } private void UpdatePhysics() { WorldIntersectionNormal ray = new WorldIntersectionNormal(); Unigine.Object hit = World.GetIntersection(node.WorldPosition, node.WorldPosition - (node.GetWorldRotation() * vec3.UP * (suspensionDistanceConstant + wheelRadius)), 1, ray); if(hit) { float distance = (float)(ray.Point - node.WorldPosition).Length; // Hooke's Law previousSuspensionDistance = currentSuspensionDistance; currentSuspensionDistance = suspensionDistanceConstant - (distance - wheelRadius); springVelocity = (currentSuspensionDistance - previousSuspensionDistance) / Game.IFps; springForce = springConstant * currentSuspensionDistance; damperForce = damperConstant * springVelocity; // Apply force to car body vehicleBody.AddWorldForce(node.GetWorldRotation() * vec3.UP * (springForce + damperForce), (vec3)node.WorldPosition); } Visualizer.RenderLine3D(node.WorldPosition, node.WorldPosition - (node.GetWorldRotation() * vec3.UP * (suspensionDistanceConstant + wheelRadius)), vec4.GREEN); } } The only major differences are getting the rays distance and replacing Time.fixedDelta with Game.IFps Edit: There is a stupid mistake in the code, AddWorldForce takes in position first, force second ofc, sadly that wasnt the fix either, its a little bit less insane now but still makes the rigidbody jump in all directions Here is also my hierarchy if it still might help Edited September 19, 2023 by igorciz777 Link to comment
igorciz777 Posted September 20, 2023 Author Share Posted September 20, 2023 Seems like an obvious fix now but i stabilized the suspension script by increasing the Physics FPS in the Settings tab. No luck with the TireModel script, it most likely needs a complete rewrite, maybe a XZY->XYZ related issue i overlooked. I think all my Intersection specific issues are solved for now, I appreciate the help! 1 Link to comment
Recommended Posts