#ok I am going to delete the code and
1 messages · Page 1 of 1 (latest)
okay so in order to implement what i said you'll need to learn a few things. We can break down what I said into several steps that would make the process simpler. i'm gonna write up a short explanation of what you'll want to look into for that
- you'll want to know how to move a kinematic rigidbody. this part is actually pretty simple, you can use the Rigidbody.MovePosition method for it
- you'll also want to learn how to use either Lerp or Vector3.MoveTowards to determine the desired position for the MovePosition() call, you'll want to increment the position over time rather than all at once so that you have smooth consistent movement
- you'll also need to know how to use physics queries, for example a boxcast could be perfect for this, you would use the boxcast to determine where the collider that will stop the object is at and make the target point half of the object's width away from that collider
- you'll also need to know how to prevent input, this part is pretty simple, you can basically handle your input in Update while doing all the movement and stuff in FixedUpdate, then in Update you can just check whether the object is at (or within a desired distance from) the target location and just
return;from Update to prevent checking for input
On point 2, Do you mean Vector2 since it is a 2D template?
Or do I still have to work with Vector 3?
i do not, even though it is 2d it still expects a Vector3 for position. you can just leave the z value at 0 though
Alright, will search everything you mentioned up and come back when I understand or do not understand.
Vector2 can be implicitly cast to Vector3 though, so you can technically use it anyway, but you should get comfortable using Vector3 if you plan to do much with unity
Ok
i would personally start with points 1 and 4, learn to move a kinematic rigidbody an arbitrary distance and disable input for the duration of the move. after that look into step 2 for moving smoothly over time, then finally step 3 for physics queries and determining the target destination
Since I am using Vector3, do I use 3D components?
nope, you can continue using 2d components. 2d still uses vector3 for a lot of things including position
Ok
actually you can use Vector2, rigidbody2d.MovePosition does expect a Vector2. only major difference between the two is that Vector2 is a Vector3 with a z axis value of 0
I am gonna use a 3D Rigidbody since IsKinematic does not exist in the RigidBody2D component. Or can I still access it with code?
the body type is where you can set the 2d rigidbody to kinematic
Ok
it can be accessed at runtime too, but you won't need to. your object (at this point in time) doesn't need to be dynamic at all
if you decide you want gravity affecting it or things to be pushing it around you can make it dynamic, otherwise you can just leave it kinematic
Does IsKinematic freeze rotation as well?
sorta, it doesn't really freeze anything at all, it just prevents the object from being affected by any types of force
Ok, I understand.
so you'd still be able to move the object and even rotate it, but it will only do what you tell it to, it won't like hit a corner and start spinning or be affected by another object colliding with it, but it can still act upon other objects
so Lerp or Vector3.MoveToward is basically where you chose a starting point and a finishing point which the object moves between?
yep, this article is a good write up on how to use Lerp: https://gamedevbeginner.com/the-right-way-to-lerp-in-unity-with-examples/
Vector3.MoveTowards works pretty similarly, it just ensures that it moves at a fixed speed rather than within a fixed time
ok
this includes an example of how to use Vector2.MoveTowards https://docs.unity3d.com/ScriptReference/Vector2.MoveTowards.html
though you should still read that first article so you get a good understanding and can decide which is the right option for you
Ok, I have looked trough all the points you mentioned and I think I am ready. I am gonna try some code myself and come back if I have any errors.
One question I have is what value should the input be instead of a char?
rather than a char you could use something like a Vector2, that way you don't have to check which direction was pressed in FixedUpdate, you just have the direction
so you'd do like:
if(Input.GetKeyDown(KeyCode.W))
inputDirection = Vector2.Up;
then in fixed update instead of comparing what direction was pressed, you just use that vector2 for the direction of movement/physics cast
you don't even need to check the input direction. it's the direction you want to move in already so you just use it
Ok, I think I understand
Do I even need to know the Direction if I am using .moveTowards?
yes, you have to get the target position somehow
you can, or you can do it in Update, doesn't make too much difference
Can't I make a method called GetTarget instead?
yep, you gotta call that from somewhere though so that can be from either Update or FixedUpdate
should the target type be a GameObject?
no, you want a target position. so a Vector2 will do
that's target position, but to get that I need to get the target.
you don't need any target object, just the position you want to get to
how do I get that?
how do I know what the target is?
Do I cast a ray to the direction I pressed?
that's what the physics query i mentioned before was for. but for now you can just pick a position an arbitrary distance from the object to make sure you understand how to move the object
once you know how to move it, you can look into getting a specific position
although, now that i think about it, an even easier way to handle this would be to just set the velocity to your desired direction * speed, then just use a physics query to determine if you have reached the target destination. that way it doesn't matter how far you travel, you'll always move at the same speed and you won't have a specific destination, you'll just be checking for when the object has stopped moving
and with a rigidbody2d you can still set the velocity even though the body is kinematic (can't do that for 3d afaik)
any other method I can use instead of transform.position?
It is moving the object instantly.
I want the player to be able to see the movement
do I use animations for that?
don't use transform.position at all. either move using Rigidbody2D.MovePosition or set the rigidbody's velocity
and that's literally the point of using Vector2.MoveToward so you move over time instead of all at once
missing new also 2d rigidbody uses Vector2 rather than Vector3
oh wait, remove new my bad. you forgot to call the MoveToward method
Vector2.MoveToward(position, target, speed)
i still think switching to using velocity would be easier though, that would just be rb.velocity = inputDirection * speed;
then you just use a physics query to check when it has collided with a wall to allow input again
to get the target position, do I create a ray cast to the targetDirection?
if you aren't using velocity then yes, you can use a raycast or boxcast then find the hit point and subtract half inputDirection * (1/2 object size) from where it hit and that would be the target position. if you use velocity you don't even need a target position, just a direction and a very short raycast to see if you have collided with something
ok. I will rest now and come back later. I have been spending 5h on just getting movements. spent 3h on a script I scrapped.
Thanks for your help.
I am using transform.position just to test if I am getting the position through the ray
you're creating a new Vector2 there which expects 2 floats, are you sure you don't want to be using Vector2.MoveToward instead?
why is it not moving when I am pressing W
can you find the problem here?
oh
i found it
with your current setup it will only move on frames you press W
ik
Is RaycastHit a type of a variable that represents the object that a raycast hits?
@flint rivet
missing () on the GetComponent call. but now you've strayed far enough away from what I recommended doing that you can probably just start asking for help in the #💻┃code-beginner channel 🤷♂️
Is this more like what you are telling me to do?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
private Rigidbody2D rb;
[SerializeField] private float speedFactor;
[SerializeField] private float speedMultiplier = 1f;
private float speed;
private Vector2 rayDirection;
private RaycastHit2D target;
private Vector2 targetPosition;
private bool isMoving;
void Start()
{
rb = GetComponent<Rigidbody2D>();
speed = speedFactor * speedMultiplier;
}
void Update()
{
if (isMoving == true)
{
transform.position = targetPosition;
}
isMoving = false;
}
private void OnGUI()
{
if (Input.GetKeyDown(KeyCode.W))
{
isMoving = true;
rayDirection = Vector2.up;
target = Physics2D.Raycast(transform.position, rayDirection);
targetPosition = target.transform.position;
}
else if (Input.GetKeyDown(KeyCode.S))
{
}
else if (Input.GetKeyDown(KeyCode.A))
{
}
else if (Input.GetKeyDown(KeyCode.D))
{
}
}
}```
The problem I am having here is that when I am pressing W, the player is not moving.
don't use the isMoving bool at all, and you're still teleporting to the end position, you want to move over time