ThaDoggFather Posted January 2, 2023 Share 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) Link to comment
Tessalator Posted January 4, 2023 Share 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 Link to comment
ThaDoggFather Posted January 6, 2023 Author Share 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! Link to comment
Recommended Posts