How to make an object follow a special raycast reflection? - c#

Here's the issue:
I have a raycast reflection that reflects normally, but when it encounters a straight wall it reflects in the X-Z plane.
I have it running (Code provided at the end of this explanation)
It looks like this:
Reflection Angle#01
Another: Reflection Angle#02
My main issue is making the bullets bounce according to my special laws of reflection, here's what I've been able to achieve by taking some help from code online:
Out of sync bullet.gif
As you can tell, the bullet is a bit skewed, I imagined it's because of the collision calculations since I turned off gravity and just use rigidbody.velocity to shoot these bullets, here's the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace StarterAssets
{
using UnityEngine;
public class CollisionDetector : MonoBehaviour
{
[SerializeField]
[Tooltip("Just for debugging, adds some velocity during OnEnable")]
private Vector3 initialVelocity;
[SerializeField]
private float minVelocity = 3f;
private Vector3 lastFrameVelocity;
private Rigidbody rb;
private void OnEnable()
{
transform.localScale = new Vector3(.5f, .5f, .5f);
rb = GetComponent<Rigidbody>();
rb.velocity = transform.forward * minVelocity;
}
private void Update()
{
lastFrameVelocity = rb.velocity;
}
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.CompareTag("Mirror"))
{
Bounce(collision.contacts[0].normal);
}
Physics.IgnoreCollision(collision.collider, GetComponent<Collider>());
}
private void Bounce(Vector3 collisionNormal)
{
rb.velocity = lastFrameVelocity;
var speed = lastFrameVelocity.magnitude;
Vector3 direction;
if (Mathf.Abs(collisionNormal.y) < .5)
{
var previousDirection = lastFrameVelocity.normalized;
previousDirection.y = 0;
var xzNormal = collisionNormal;
xzNormal.y = 0;
direction = Vector3.Reflect(previousDirection, xzNormal);
}
else
direction = Vector3.Reflect(lastFrameVelocity.normalized, collisionNormal);
Debug.Log("Out Direction: " + direction);
//rb.AddForce(direction * Mathf.Max(speed, minVelocity));
rb.velocity = direction * minVelocity;
}
}
}
Here's the code for the laser reflections:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(LineRenderer))]
public class RaycastReflection : MonoBehaviour
{
public int reflections;
public float maxLength;
private LineRenderer lineRenderer;
private Ray ray;
private RaycastHit hit;
//private Vector3 direction;
// Start is called before the first frame update
void Start()
{
lineRenderer = GetComponent<LineRenderer>();
}
// Update is called once per frame
void Update()
{
ray = new Ray(transform.position, transform.forward);
//lineRenderer.material.color = Color.cyan;
lineRenderer.positionCount = 1;
lineRenderer.SetPosition(0, transform.position);
float remainingLength = maxLength;
for (int i = 0; i < reflections; i++)
{
if (Physics.Raycast(ray.origin, ray.direction, out hit, remainingLength,~(1 << 2)))
{
lineRenderer.positionCount += 1;
lineRenderer.SetPosition(lineRenderer.positionCount - 1, hit.point);
remainingLength -= Vector3.Distance(ray.origin, hit.point);
if(Mathf.Abs(hit.normal.y) <.5)
{
var previousDirection = ray.direction;
previousDirection.y = 0;
var xzNormal = hit.normal;
xzNormal.y = 0;
//var direction = Vector3.Reflect(previousDirection, xzNormal);
ray = new Ray(hit.point, Vector3.Reflect(previousDirection, xzNormal));
}
else
{
ray = new Ray(hit.point, Vector3.Reflect(ray.direction, hit.normal));
}
if (hit.collider.tag == "Totem")
{
//lineRenderer.material.color = new Color(0.4f, 0.9f, 0.7f, 1.0f);
break;
}
if (hit.collider.tag != "Mirror")
{
break;
}
}
else
{
lineRenderer.positionCount += 1;
lineRenderer.SetPosition(lineRenderer.positionCount - 1, ray.origin + ray.direction * remainingLength);
}
}
}
}
One of the easiest solutions I could think was to make the sphere/box collider extremely small, the collisions wouldnt cause a massive issue, and at slow speeds, this is true, it functions almost exactly like it's supposed to, but at higher speeds it's completely off the path again.
Another solution was to calculate the ray again from the cube, get the value of the hit.point reflections and put that inside the direction variable, use that to change my velocity each time,
Sadly doesn't work that conveniently
Here's my attempt:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace StarterAssets
{
using UnityEngine;
public class CollisionDetector : MonoBehaviour
{
[SerializeField]
[Tooltip("Just for debugging, adds some velocity during OnEnable")]
private Vector3 initialVelocity;
[SerializeField]
private float minVelocity = 2f;
private Vector3 lastFrameVelocity;
private Rigidbody rb;
private Ray ray;
private RaycastHit hit;
private void OnEnable()
{
ray = new Ray(transform.parent.parent.position, transform.parent.parent.forward);
Physics.Raycast(ray.origin, ray.direction, out hit, 20000, ~(1 << 2));
transform.localScale = new Vector3(.15f, .15f, .15f);
rb = GetComponent<Rigidbody>();
// rb.AddForce(ray.direction * minVelocity, ForceMode.Impulse);
rb.velocity = ray.direction * minVelocity;
}
private void Update()
{
lastFrameVelocity = rb.velocity;
}
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.CompareTag("Mirror"))
{
Bounce(collision.contacts[0].normal);
}
else
Physics.IgnoreCollision(collision.collider, GetComponent<Collider>());
}
private void Bounce(Vector3 collisionNormal)
{
//var speed = lastFrameVelocity.magnitude;
Vector3 direction;
// transform.SetPositionAndRotation(hit.point, lastRotation);
transform.position = hit.point;
if (Mathf.Abs(hit.normal.y) < .5)
{
//var previousDirection = lastFrameVelocity.normalized;
//previousDirection.y = 0;
//var xzNormal = collisionNormal;
//xzNormal.y = 0;
//direction = Vector3.Reflect(previousDirection, xzNormal);
var previousDirection = ray.direction;
previousDirection.y = 0;
var xzNormal = hit.normal;
xzNormal.y = 0;
direction = Vector3.Reflect(previousDirection, xzNormal);
ray = new Ray(hit.point, direction);
}
else {
//direction = Vector3.Reflect(lastFrameVelocity.normalized, collisionNormal);
direction = Vector3.Reflect(ray.direction, hit.normal);
ray = new Ray(hit.point, direction);
}
Physics.Raycast(ray.origin, ray.direction, out hit, 20000, ~(1 << 2));
Debug.Log("Out Direction: " + direction);
//rb.AddForce(direction * Mathf.Max(speed, minVelocity));
//rb.velocity = direction * Mathf.Max(speed, minVelocity);
//rb.AddForce(direction * minVelocity, ForceMode.Impulse);
rb.velocity = direction * minVelocity;
}
}
I've also tried Vector3.MoveTowards and .Lerp, but I wasn't able to do it properly.
Please help! I have no idea how to make this darn bullet follow the laser path.

Related

Horizontal movement of player causes egregious numbers when checking vertical velocity

Player movement is working (at least somewhat) now, however one issue remains, and that's the insane numbers the y velocity of the Rigidbody2D on the player. Since the isGrounded check I plan to add will use velocity for the sake of stability, this needs to be fixed.
It confuses me, considering the velocity is 0 normally, but whenever moving left or right it changes to said high numbers.
Movement code:
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class PlayerM : MonoBehaviour
{
private PControls control;
Rigidbody2D rb;
SpriteRenderer sp;
Transform tr;
public float speed = 0f;
public float speedC;
public float heightSpeed = 5f;
public float heightC;
public bool grounded;
void Start()
{
control = new PControls();
control.Enable();
rb = GetComponent<Rigidbody2D>();
sp = GetComponent<SpriteRenderer>();
tr = GetComponent<Transform>();
}
// Update is called once per frame
void FixedUpdate()
{
RaycastHit2D hit = Physics2D.Raycast(rb.position, -Vector2.up);
Color color = new Color(0, 0, 1.0f);
Debug.DrawRay(transform.position, Vector2.down);
speedC = rb.velocity.magnitude;
var pos = control.Movement.Move.ReadValue<float>();
float GetVerticalSpeed() => rb.velocity.y;
if(pos == -1)
{
sp.flipX = true;
}
else if(pos == 1)
{
sp.flipX = false;
}
if((pos == 0) && (speed > 0.1f))
{
speed -= 3f * Time.deltaTime;
}
else if(speed < 1.4f)
{
speed += Mathf.Abs(pos) * 8 * Time.deltaTime;
}
if(speedC < 7f)
{
rb.AddForce(new Vector3((pos * 5), 0f) * speed * Time.deltaTime, ForceMode2D.Impulse);
}
var jump = control.Movement.Jump.ReadValue<float>();
Debug.Log(GetVerticalSpeed());
Vector3 v = rb.velocity;
v.y = 10;
if(jump == 1)
{
rb.velocity = v;
}
}
}
Seems the main issue was fixed by converting the height velocity to an integer using System.Math.Round():
float vel = rb.velocity.y;
heightC = (int)System.Math.Round(vel);
Not sure it's the best solution, but it's something..

Unity 2D - Moving Any Object Between Two (or more) Spaces

new Unity person, and new coder in general. I'm trying to have an object move back and forth between two spots. I have it right now going from Point 1 to Point 2, but it stops. I tried a do loop, and to call back the Move() function again but it just froze Unity.
I'm guessing I need some sort of Loop, but not sure where to do it? I wouldn't mind having the ability to add more spots as well. I have waypoints in Unity itself, tied to the Object. Thanks!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ZombiePathing : MonoBehaviour
{
[SerializeField] List<Transform> waypoints;
[SerializeField] float moveSpeed = 2f;
int waypointIndex = 0;
void Start()
{
transform.position = waypoints[waypointIndex].transform.position;
}
// Update is called once per frame
void Update()
{
Move();
}
private void Move()
{
if (waypointIndex <= waypoints.Count -1)
{
var targetPosition = waypoints[waypointIndex].transform.position;
var movementThisFrame = moveSpeed * Time.deltaTime;
transform.position = Vector2.MoveTowards
(transform.position, targetPosition, movementThisFrame);
if (transform.position == targetPosition)
{
waypointIndex++;
}
}
}
}
just add an index equal to 1 or -1 depends on the current transform,
I wrote this code very quickly so it's unsorted, and I do my best to make it very close to your code with some edits.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ZombiePathing : MonoBehaviour
{
[SerializeField] List<Transform> waypoints;
[SerializeField] float moveSpeed = 2f;
Vector3 targetPosition;
int waypointIndex = 0;
int index = 1;
void Start()
{
transform.position = waypoints[waypointIndex].position;
UpdateTransform();
}
void Update()
{ transform.position = Vector2.MoveTowards
(transform.position, targetPosition, moveSpeed * Time.deltaTime);
if (transform.position == targetPosition) UpdateTransform();
}
private void UpdateTransform()
{
waypointIndex += index;
targetPosition = waypoints[waypointIndex].position;
if (waypointIndex >= waypoints.Count -1) index = -1;
else if (waypointIndex <= 0 && index == -1)index = 1;
}
}

Power charge shot while holding mousebuttondown

I have a script which fires a linerenderer from a start to end position with each click. I want to have a linerender that is constant until the mouse button is released. Like a power charge. What do I need to add in the script to make this happen?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RayCastShot : MonoBehaviour
{
public float fireRate = 0.25f;
public float weaponRange = 50f;
public float hitForce = 100f;
public Transform gunEndLeft;
public Transform gunEndRight;
private Camera fpsCam;
private WaitForSeconds shotDuration = new WaitForSeconds(0.07f);
private LineRenderer lineRenderer;
private float nextFire;
public Material mat1;
public Material mat2;
void Start()
{
lineRenderer = GetComponent<LineRenderer>();
fpsCam = GetComponent<Camera>();
}
void Update()
{
if (Input.GetButtonDown("Fire1") && Time.time > nextFire)
{
nextFire = Time.time + fireRate;
StartCoroutine(ShotEffect());
Vector3 rayOrigin = fpsCam.ViewportToWorldPoint(new Vector3(0.5f, 0.5f, 0.0f));
RaycastHit hit;
lineRenderer.SetPosition(0, gunEndLeft.position);
lineRenderer.material = mat1;
if (Physics.Raycast(rayOrigin, fpsCam.transform.forward, out hit, weaponRange))
{
lineRenderer.SetPosition(1, hit.point);
//get reference to hit point
}
if(hit.rigidbody !=null)
{
hit.rigidbody.AddForce(-hit.normal * hitForce);
}
else
{
lineRenderer.SetPosition(1, rayOrigin + (fpsCam.transform.forward * weaponRange));
}
}
if (Input.GetButtonDown("Fire2") && Time.time > nextFire)
{
nextFire = Time.time + fireRate;
StartCoroutine(ShotEffect());
Vector3 rayOrigin = fpsCam.ViewportToWorldPoint(new Vector3(0.5f, 0.5f, 0.0f));
RaycastHit hit;
lineRenderer.SetPosition(0, gunEndRight.position);
lineRenderer.material = mat2;
//lineRenderer.material = new Material(Shader.Find("Particles/Priority Additive"));
if (Physics.Raycast(rayOrigin, fpsCam.transform.forward, out hit, weaponRange))
{
lineRenderer.SetPosition(1, hit.point);
//get reference to hit point
}
if (hit.rigidbody != null)
{
hit.rigidbody.AddForce(-hit.normal * hitForce);
}
else
{
lineRenderer.SetPosition(1, rayOrigin + (fpsCam.transform.forward * weaponRange));
}
}
}
private IEnumerator ShotEffect()
{
lineRenderer.enabled = true;
yield return shotDuration;
lineRenderer.enabled = false;
}
}
Well you can start by use Input.GetButtonUp to stop the fire.
That way you can start on Input.GetButtonDown and stop only when buttonUp.
If you need to execute code every frame you can also use Input.GetButton.
That's the basic idea.

Getting the distance of wall(Multiple objects with same tag)

I'm trying to get the distance between my player, and the nearest object with the tag 'wall' however I can't seem to get it to work.
To my knowledge my code isn't working at all.
So my question is;
What am I doing wrong? Again, I want to find the distance from my player and the nearest object with the tag 'wall'. If I'm near a object with the tag 'wall' I want it to set the variable to true.(nearWall = true) then once I'm away from the object(About 10.0f) I want it back to false.(nearWall = false)
This is the code I have been working with.
using UnityEngine;
using System.Collections;
public class PlayerMotor : MonoBehaviour {
private CharacterController controller;
private Vector3 moveVector;
private float speed = 2.0f;
private float verticalVelocity = 0.0f;
private float gravity = 12.0f;
private bool nearWall;
public GameObject playerObject;
GameObject closestObject;
float distance = Mathf.Infinity;
public float distanceToWall = Mathf.Infinity;
private void Start() {
nearWall = false;
playerObject = GameObject.Find("Player");
distanceToWall = 0;
controller = GetComponent<CharacterController> ();
}
public void getNearestWall()
{
if (distance <= 10.0f) {
nearWall = true;
print ("Near wall!");
}
else
nearWall = false;
}
GameObject findNearestWall()
{
GameObject[]objectArray;
objectArray = GameObject.FindGameObjectsWithTag("wall");
Vector3 position = playerObject.transform.position;
foreach(GameObject currentObject in objectArray)
{
Vector3 distanceCheck = currentObject.transform.position - position;
float currentDistance = distanceCheck.sqrMagnitude;
if (currentDistance < distance)
{
closestObject = currentObject;
distance = currentDistance;
}
}
return closestObject;
}
private void Update()
{
findNearestWall ();
moveVector = Vector3.zero;
if (controller.isGrounded)
{
verticalVelocity = -0.5f;
}
else
{
verticalVelocity -= gravity * Time.deltaTime;
}
if (Input.GetMouseButton (0)) {
if (!nearWall) {
if (Input.mousePosition.x > Screen.width / 2)
moveVector.x = speed;
else
moveVector.x = -speed;
}
else
{
moveVector.x = transform.forward.x * speed;
transform.Rotate(new Vector3(0, -90, 0));
}
}
moveVector.y = verticalVelocity;
moveVector.z = transform.forward.z * speed;
controller.Move (moveVector * Time.deltaTime);
}
}
One thing is that you are not calling getNearestWall() method - which is actually changing the flag - anywhere.
And second why don't you just try:
currentDistance = Vector3.Distance(currentObject.transform.position, position);
When calculating distance
first of all you need to call getNearestWall(); inside the Update() method ( after findNearestWall() of course ). also what you are doing now is getting the minimal distance the player reached in the whole game. you might want to add distance = Mathf.Infinity; in top of findNearestWall() so it will something like this:
GameObject findNearestWall()
{
GameObject[] objectArray;
objectArray = GameObject.FindGameObjectsWithTag("wall");
distance = Mathf.Infinity;
Vector3 position = playerObject.transform.position;
foreach (GameObject currentObject in objectArray)
{
Vector3 distanceCheck = currentObject.transform.position - position;
float currentDistance = distanceCheck.sqrMagnitude;
if (currentDistance < distance)
{
closestObject = currentObject;
distance = currentDistance;
}
}
return closestObject;
}
now whenever you get near a wall it should print Near wall!
note:
also you are calling FindObjectsWithTag() at an Update method which might significantly drain your processing power. you might want to avoid that by declaring a private GameObject[] objectArray in the class.
and then use objectArray = GameObject.FindGameObjectsWithTag("wall"); once at Awake() or Start()

Smooth fall in Unity - C#

I am working on a Character Controller Script and everything is working fine but the problem is that once my player starts to fall it is so sudden and jerks down. I would like the player to gradually fall down, this is my character controller script -
using UnityEngine;
using System.Collections;
public class CharacterController : MonoBehaviour {
public float inputDelay = 0.1f;
public float forwardVel = 12;
public float rotateCel = 12;
public float JumpHeight = 20;
public Vector3 Gravity = new Vector3 (0, -180, 0);
public bool CanPress;
private float jumpTime;
public float _initialJumpTime = 0.4f;
//[HideInInspector]
public bool isGrounded;
Quaternion targetRotation;
Rigidbody rBody;
Vector3 forwardInput, turnInput;
public bool HasJumped;
public Quaternion TargetRotation
{
get {return targetRotation;}
}
// Use this for initialization
void Start () {
Physics.gravity = Gravity;
targetRotation = transform.rotation;
if (GetComponent<Rigidbody> ())
rBody = GetComponent<Rigidbody> ();
else {
Debug.LogError("Character Needs Rigidbody");
}
// forwardInput = turnInput = 0;
forwardInput = turnInput = Vector3.zero;
}
// Update is called once per frame
void Update () {
GetInput ();
//Turn ();
if (CanPress == true) {
if (Input.GetKeyDown (KeyCode.Space)) {
HasJumped = true;
jumpTime = _initialJumpTime;
}
}
if (HasJumped == true) {
rBody.useGravity = false;
jumpTime -= 1 * Time.deltaTime;
if (jumpTime > 0) {
Jump();
}
else {
HasJumped = false;
rBody.useGravity = true;
}
}
}
void GetInput() {
//forwardInput = Input.GetAxis ("Vertical");
//turnInput = Input.GetAxis ("Horizontal");
forwardInput = new Vector3 (Input.GetAxis ("Horizontal") * rotateCel, 0, Input.GetAxis ("Vertical") * forwardVel);
forwardInput = transform.TransformDirection (forwardInput);
if (Input.GetKeyUp (KeyCode.Space)) {
//HasJumped = false;
}
}
void Jump() {
Vector3 up = transform.TransformDirection (Vector3.up);
GetComponent<Rigidbody> ().AddForce (up * 5, ForceMode.Impulse);
}
void FixedUpdate() {
Run ();
}
void Run() {
if (Mathf.Abs (10) > inputDelay) {
//Move
//rBody.velocity = transform.forward * forwardInput * forwardVel;
rBody.velocity = forwardInput;
} else {
//zero velocity
rBody.velocity = Vector3.zero;
}
}
void Turn() {
// targetRotation *= Quaternion.AngleAxis (rotateCel * turnInput * Time.deltaTime, Vector3.up);
// transform.rotation = targetRotation;
}
void OnTriggerEnter(Collider col) {
isGrounded = true;
CanPress = true;
}
void OnTriggerExit(Collider col) {
isGrounded = false;
CanPress = false;
}
}
My character has a Rigidbody attactches which uses gravity and has X,Y,Z constraints for Rotation.
The player goes up smoothly and falls down smoothly but the transition between the two is very abrupt and sudden.
Thanks for the help. :)
Okay, so I took your code and had a play.
I think the issue was that in your Run() function, you were altering the velocity of the rigidbody which was affecting your jumping.
I've taken that stuff out and improved your script slightly and tested it. Attach this to a capsule with a rigidbody on it, with a floor underneath with a box collider on and hit space, and you should get a smooth jump.
Your new(ish) script:
using UnityEngine;
using System.Collections;
public class CharacterController : MonoBehaviour
{
public float inputDelay = 0.1f;
public float forwardVel = 12;
public float rotateCel = 12;
public float jumpHeight = 10;
private float jumpTime;
public float _initialJumpTime = 0.4f;
//[HideInInspector]
public bool isGrounded;
Quaternion targetRotation;
Rigidbody rBody;
Vector3 forwardInput, turnInput;
public bool canJump;
public Quaternion TargetRotation
{
get { return targetRotation; }
}
void Start()
{
targetRotation = transform.rotation;
if (GetComponent<Rigidbody>())
rBody = GetComponent<Rigidbody>();
else
{
Debug.LogError("Character Needs Rigidbody");
}
// forwardInput = turnInput = 0;
forwardInput = turnInput = Vector3.zero;
}
void Update()
{
GetInput();
//Turn ();
if (Input.GetKeyDown(KeyCode.Space) && canJump)
{
rBody.AddForce(Vector3.up * jumpHeight, ForceMode.Impulse);
}
}
void GetInput()
{
//forwardInput = Input.GetAxis ("Vertical");
//turnInput = Input.GetAxis ("Horizontal");
forwardInput = new Vector3(Input.GetAxis("Horizontal") * rotateCel, 0, Input.GetAxis("Vertical") * forwardVel);
forwardInput = transform.TransformDirection(forwardInput);
}
void FixedUpdate()
{
//Run();
}
void Run()
{
//HERE YOU SET THE RIGIDBODYS VELOCITY, WHICH IS CAUSING YOUR JUMP TO NOT WORK PROPERLY. DO NOT MODIFY THE VELOCITY
//OF A RIGIDBODY
if (Mathf.Abs(10) > inputDelay)
{
//Move
//rBody.velocity = transform.forward * forwardInput * forwardVel;
rBody.velocity = forwardInput;
}
else
{
//zero velocity
rBody.velocity = Vector3.zero;
}
}
void Turn()
{
// targetRotation *= Quaternion.AngleAxis (rotateCel * turnInput * Time.deltaTime, Vector3.up);
// transform.rotation = targetRotation;
}
void OnCollisionEnter(Collision col)
{
isGrounded = true;
canJump = true;
}
void OnCollisionExit(Collision col)
{
isGrounded = false;
canJump = false;
}
}
Couple of points:
name your variables inThisKindOfFashion (jumpHeight, isOnGround, camelCaseExample), having variables beginning with a capital letter like Gravity and JumpHeight can get confusing.
as someone once answered on one of my questions, don't modify the velocity of a rigidbody unless you know what you are doing! Seems odd, but after following that advice I've never had a problem since!
In your script I have used OnCollision rather than OnTrigger. If you put a floor with a box collider underneath your capsule with a collider, rigidbody and this script on, your character will stop on the ground. If you use a trigger, he will fall through (at least in my experience!)
Happy coding! :-)
Edit
To respond to your comments:
"How do you suggest I move the player"
Movement can be done in a variety of different ways, but I usually use this one all the time unless I need to do something a bit differently:
void Update()
{
if (Input.GetKeyDown(KeyCode.LeftArrow))
{
transform.position += Vector3.left * speed * Time.deltaTime; //speed could be 5f, for example (f means float);
}
// then do the same for other directions, RightArrow -.right, UpArrow - .forward, DownArrow - .back
}
"How do I adjust how fast the player jumps"
You can alter the jumpHeight variable for a higher or smaller jump. If by faster you mean falls down faster, go to Edit>Project Settings>Physics> and change Y gravity to something smaller, such as -20.
Tutorials can be found here
They have a wide variety of tutorials, and even have ones that come with example projects so you can just put it together following the video.

Categories

Resources