Asked by Coder
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Controller : MonoBehaviour
{
public Rigidbody rb;
public float jumpForce;
public float speed;
public float moveX;
public float moveY;
void Start()
{
if (rb == null)
{
rb = GetComponent<Rigidbody>();
}
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
}
moveX = Input.GetAxis("Horizontal");
moveY = Input.GetAxis("Vertical");
transform.Translate(Vector3.forward * speed * moveY * Time.deltaTime);
transform.Translate(Vector3.right * speed * moveX * Time.deltaTime);
}
}
Make it simple physics based movement instead
All Answers 1
Answered by
GPT-5 mini
AI
Here’s a simple physics-based movement controller that uses the Rigidbody for movement and jumping. It moves by setting the Rigidbody velocity (so collisions and physics behave naturally) and handles jumping in FixedUpdate via a jump-request flag set in Update. It also includes a basic grounded check using collision normals.
Paste this on the same GameObject that has the Rigidbody (make sure the Rigidbody is not kinematic):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Controller : MonoBehaviour
{
public Rigidbody rb;
public float speed = 5f; // horizontal move speed
public float jumpForce = 5f; // impulse applied when jumping
private float moveX;
private float moveY;
private bool isGrounded;
private bool jumpRequested;
void Start()
{
if (rb == null) rb = GetComponent<Rigidbody>();
}
void Update()
{
// read input in Update for responsiveness
moveX = Input.GetAxis("Horizontal");
moveY = Input.GetAxis("Vertical");
if (Input.GetKeyDown(KeyCode.Space) && isGrounded)
{
jumpRequested = true;
}
}
void FixedUpdate()
{
// Build horizontal movement vector relative to player orientation
Vector3 move = (transform.right * moveX + transform.forward * moveY);
Vector3 horizontalVel = move.normalized * speed;
// Preserve vertical velocity (gravity, jumps) and apply horizontal velocity
rb.velocity = new Vector3(horizontalVel.x, rb.velocity.y, horizontalVel.z);
// Apply jump impulse if requested
if (jumpRequested)
{
rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
jumpRequested = false;
}
}
void OnCollisionEnter(Collision collision)
{
CheckGroundCollision(collision);
}
void OnCollisionStay(Collision collision)
{
CheckGroundCollision(collision);
}
void OnCollisionExit(Collision collision)
{
// Simple approach: when leaving contact, mark not grounded. OnCollisionStay/Enter will set true again.
isGrounded = false;
}
private void CheckGroundCollision(Collision col)
{
// If any contact normal points mostly upward, consider the player grounded
foreach (ContactPoint cp in col.contacts)
{
if (cp.normal.y > 0.5f)
{
isGrounded = true;
return;
}
}
}
}
Tips:
- Make sure the Rigidbody's “Constraints” freeze X/Z rotation if you don't want the player to tip over.
- Consider setting Rigidbody.interpolation = Interpolate for smoother visuals.
- If you want acceleration instead of instant velocity changes, use rb.AddForce with ForceMode.Acceleration or Lerp the velocity toward the target.
- If you want to support double jumps, remove the isGrounded check for jump or add counters.
If you want an alternative that uses rb.MovePosition (kinematic-like smooth movement) or that uses AddForce for acceleration, tell me which behavior you prefer and I’ll provide that version.
Paste this on the same GameObject that has the Rigidbody (make sure the Rigidbody is not kinematic):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Controller : MonoBehaviour
{
public Rigidbody rb;
public float speed = 5f; // horizontal move speed
public float jumpForce = 5f; // impulse applied when jumping
private float moveX;
private float moveY;
private bool isGrounded;
private bool jumpRequested;
void Start()
{
if (rb == null) rb = GetComponent<Rigidbody>();
}
void Update()
{
// read input in Update for responsiveness
moveX = Input.GetAxis("Horizontal");
moveY = Input.GetAxis("Vertical");
if (Input.GetKeyDown(KeyCode.Space) && isGrounded)
{
jumpRequested = true;
}
}
void FixedUpdate()
{
// Build horizontal movement vector relative to player orientation
Vector3 move = (transform.right * moveX + transform.forward * moveY);
Vector3 horizontalVel = move.normalized * speed;
// Preserve vertical velocity (gravity, jumps) and apply horizontal velocity
rb.velocity = new Vector3(horizontalVel.x, rb.velocity.y, horizontalVel.z);
// Apply jump impulse if requested
if (jumpRequested)
{
rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
jumpRequested = false;
}
}
void OnCollisionEnter(Collision collision)
{
CheckGroundCollision(collision);
}
void OnCollisionStay(Collision collision)
{
CheckGroundCollision(collision);
}
void OnCollisionExit(Collision collision)
{
// Simple approach: when leaving contact, mark not grounded. OnCollisionStay/Enter will set true again.
isGrounded = false;
}
private void CheckGroundCollision(Collision col)
{
// If any contact normal points mostly upward, consider the player grounded
foreach (ContactPoint cp in col.contacts)
{
if (cp.normal.y > 0.5f)
{
isGrounded = true;
return;
}
}
}
}
Tips:
- Make sure the Rigidbody's “Constraints” freeze X/Z rotation if you don't want the player to tip over.
- Consider setting Rigidbody.interpolation = Interpolate for smoother visuals.
- If you want acceleration instead of instant velocity changes, use rb.AddForce with ForceMode.Acceleration or Lerp the velocity toward the target.
- If you want to support double jumps, remove the isGrounded check for jump or add counters.
If you want an alternative that uses rb.MovePosition (kinematic-like smooth movement) or that uses AddForce for acceleration, tell me which behavior you prefer and I’ll provide that version.
Submit Your Answer
We prioritize human answers over AI answers.
If you are human, and you can answer this question, please submit your answer.