ThaDoggFather Posted January 2, 2023 Posted January 2, 2023 (edited) Hello, please excuse me for my lack of knowledge lol. This is my first time learning C# and I've started off following basic Unity tutorials for a player controller, but I've been struggling mainly with making an efficient jump button where there is a boolean that switches true/false on collision with the raycast. Here is my code for reference: public class RaycastJump : Component { [ShowInEditor] Node Bot, gChecc; [Parameter(Title = "Jump Key")] public Input.KEY JumpKey = Input.KEY.SPACE; [ParameterSlider(Min = 1.0f, Max = 80.0f)] public float JumpForce = 40.0f; Player player; WorldIntersection Ray; Unigine.Object Obj; void Init() { Visualizer.Enabled = true; } private void Update() { var from = Bot.WorldPosition; var to = gChecc.WorldPosition; WorldIntersectionNormal Ray = new WorldIntersectionNormal(); World.GetIntersection(from, to, 1, Ray); dvec3 point = Ray.Point; Visualizer.RenderVector(point, to, vec4.ONE, arrow_size: 0.2f); } void UpdatePhysics() { if (Input.IsKeyPressed(JumpKey) && isGrounded()) Jump(Bot.ObjectBodyRigid.GetWorldVelocity(vec3.UP)); } private bool isGrounded() { return gChecc.GetWorldTrigger(1); } void Jump(vec3 Up) { Bot.ObjectBodyRigid.AddLinearImpulse(vec3.UP * JumpForce); } } Edited January 3, 2023 by ThaDoggFather More specific (using a Boolean)
Tessalator Posted January 4, 2023 Posted January 4, 2023 You have way too much going on in one place and tons of dead code there. Let's start over. Think of a component as an interface and/or extension on a node. Your problem has two parts: 1) Find Height 2) Jump If on ground Both parts act on the same node. For Part 1, Height is a measure relative to another object - "Ground". In your case, "ground" (prob) isn't a specific object - you can jump on anything you are standing on. You need to detect any item below (-z) you, and in contact/intersecting with you. "Ground" isn't changed so it's just a temp value. So, there is just one object to deal with "Bot". And we are only modifying the position of Bot's node. We can build a generic "Jumper" component for Bot (and anything traceable to a node). You said you wanted a ray cast approach. The first part of the problem, "detecting below", has a basic pattern var a_ = Position; var b_ = a_ with { z = a_.z - detectRange }; GetIntersection(a_, b_, mask, out Intersection c_); The simplest approach to just detecting "being on" something is to set your detect range small: var b_ = Position with { z = a_.z - 0.01f }; If there is a surface directly below a Point "Position" and within 0.01, it is detected. Floats can get fuzzy with small deltas though, so it's not really a solid approach without some clamping/hysteresis. If "Position" is a bodied object things are a little different. If you get "node.WorldPosition", the point you get is most likely in the mesh interior. A trace will detect the mesh surfaces. There are lot of ways to deal with this. One is to start from a point outside the object. "node.WorldBoundBox.minimum.z" gives us a point on the outer shell. Searching below is pretty common, so we can write a little node extension for that. internal static class UNodeExtensions { internal static (dvec3 source, dvec3 hit, double height, UO obj, int surface) DetectBelow(this UN node, double detectRange, int mask) { dvec3 a_ = node.WorldPosition with { z = node.WorldBoundBox.minimum.z }; dvec3 b_ = a_ with { z = a_.z - detectRange }; WorldIntersection c_ = new WorldIntersection(); UO d_ = World.GetIntersection(a_, b_, mask, c_); return (a_, c_.Point, a_.z - c_.Point.z, d_, c_.Surface); } } This returns some stuff for us. We're mainly after height in this case, but we can grab some stuff while we're there. Height // Above Surface Object, Surface // What we are above Source, Hit // Support Visualizer etc. Now we create a Component. Your component runs every physics tick and uses keyboard (space) input. IsKeyPressed fires every tick. I don't know if you meant to use IsKeyDown (one-shot), but we'll go with this. We just need to gate the input. We can also add a little hysteresis and "thicken" the ground. As long as height is below the threshold Bot "IsGrounded". using System.Diagnostics; using Unigine; using UN = Unigine.Node; using UO = Unigine.Object; public class Jumper : Component { [ShowInEditor] [Parameter(Title = "Jump Key")] internal Input.KEY jumpKey = Input.KEY.SPACE; [ShowInEditor] [ParameterSlider(Min = 1.0f, Max = 80.0f)] internal float jumpForce = 5.0f; [ShowInEditor] [ParameterSlider(Min = .0f, Max = 40.0f)] internal double maxDetectRange = 10f; [ShowInEditor] [ParameterSlider(Min = 0.001f, Max = 1.0f)] internal double groundZoneHeight = 0.01f; [ShowInEditor] [ParameterSlider(Min = 0.1f, Max = 1.0f)] internal float deadZoneTime = 0.1f; public bool isGrounded => InGroundZone; public double Height { get; private set; } = 0; bool IsJump => Input.IsKeyPressed(jumpKey) && !InDeadTime; float deadTimeMark = 0; bool InDeadTime => Game.Time < deadTimeMark; bool InGroundZone => Height < groundZoneHeight; void MakeDeadTime() => deadTimeMark = Game.Time + deadZoneTime; void UpdatePhysics() { (dvec3 a_, dvec3 b_, Height, _, _) = node.DetectBelow(maxDetectRange, 0xFFFFFFF); if (IsJump) TryJump(jumpForce); Visualizer.RenderVector(a_, b_, vec4.ONE, arrow_size: 0.2f); Debug.WriteLine(Height); } void TryJump(float force) { if (!InGroundZone) return; MakeDeadTime(); node.ObjectBodyRigid.AddLinearImpulse(vec3.UP * force); } } You can put the Visualizer stuff in Main or other places Engine.Init(args); Visualizer.Enabled = true; Unigine.Console.Onscreen = true; You don't need all of those variables and stuff. Use the built-in parts and static classes to do to things. Keep your components small and focused. Test this by putting a capsule in the world and adding this component. 2
ThaDoggFather Posted January 6, 2023 Author Posted January 6, 2023 Hey thank you so much for this, I'd been trying for a while now but got stuck into making my world for a bit. I'll go over it a few times to grasp a better understanding, and if I don't get back to you then thanks a bunch!
Recommended Posts