I'm attempting to make a raycast for a laser that will have some level of inaccuracy when fired. I was doing this with a method that creates a vector3 with some random values and adding it to the forward direction of the object firing the laser. This however seems to occasionally make the raycast clip through the object without hitting it. The code I added is debug testing to figure out this problem.
private void FixedUpdate()
{
Vector3 attackDirection = transform.TransformDirection(Vector3.forward + new Vector3(0.2f, 0.0f, 0.0f));
RaycastHit hit;
if (Physics.Raycast(transform.position, attackDirection, out hit, Mathf.Infinity))
{
Debug.DrawLine(transform.position, hit.point);
}
else
{
Debug.DrawLine(transform.position, attackDirection * 50);
}
Vector3 directionToTarget = (target.transform.position - transform.position);
Aiming(directionToTarget);
OrbitAroundTarget();
}
The object firing the raycast is orbiting around the object it's supposed to be hitting.
Both objects have box colliders and rigidbodies that are kenetic.
This is also happening if the code is executing in FixedUpdate or Update.
The Aiming method makes the object Quaternion.Slerp to look at it's target and the Orbit method makes the object transform.RotateAround it's target.
Related
I started a new game project, and I have tried to find a way to only use a rigidbody2D component to move my player game object instead of using transform.position. And I can't come up with a good way to do it or find a tutorial or documentation about it.
I have got it to work with transform.position, but how could I do it with rigidbody2D?
For movement with RigidBody2D you have mutiple options which are physics based.
I assume that's the reason you want to use RigidBody2D in the first place.
RigidBody2D obj = GetComponent();
private void moveBody()
{
//direction towards your goal
Vector2D v = mousePosition - transform.position;
//Example 1 set the velocity
obj.velocity = v;
//Example 2 apply force
obj.AddForce(v, ForceMode2D.Impulse);
}
you can read more about RigidBody2D movement
here
You can throw an invisible collider on your stage and move your object to the position you want with the ray.
Ray ray;
public RaycastHit hit;
private void Update()
{
ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit, 100f))
{
Debug.DrawRay(Camera.main.transform.position,hit.point);
transform.position = hit.point;
}
}
Best.
Im scratching my head over this one, really cant figure it out.
Im trying to implement the player movement from this example:
https://www.youtube.com/watch?v=LNidsMesxSE
Starts at minute 4:25 and ends at minute 5:20
This script tries translating all that to unity.So I started all the way over from scratch and just want to make a simple movement script.
You can plug this into any Unity version, throw the script onto and object with a CharacterController component, add a child object with a mesh that will tilt, the main object will rotate around its Y axis and move.
I do recommend using a simple T pose character or atleast a long capsule so you can better see what is happening than when you would be using a cube to test this.
The weird glitches im having is that the object randomly spasms out even though im always only adding extremely small rotations and movements every frame. And 95% of the time it doesnt happen, so I havent been able to pinpoint exactly what is causing this.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CharacterMove : MonoBehaviour
{
public float speed = 200f;
public float rotationSpeed = 180f;
public float tiltFactor = 8f;
public bool normalizeVelocity = false;
CharacterController cc;
Vector3 velocity;
Transform armatureBody;
void Start()
{
cc = GetComponent<CharacterController>();
armatureBody = transform.GetChild(0);
}
void Update()
{
velocity = new Vector3(Input.GetAxis("Horizontal"), 0,
Input.GetAxis("Vertical"));
}
void FixedUpdate()
{
if ((velocity != Vector3.zero))
{
var ccVelocity = cc.velocity; // CharacterController velocity. This might be the problem, but without it I cannot rotate the object towards the actual forward velocity.
Quaternion toRotation;
toRotation = Quaternion.LookRotation(ccVelocity, Vector3.up);
transform.rotation = Quaternion.RotateTowards(transform.rotation, toRotation, rotationSpeed * Time.deltaTime);
if (Input.GetKey(KeyCode.S)) print("new toRotation: " + toRotation);
armatureBody.localEulerAngles = new Vector3(velocity.z * tiltFactor, 0, -velocity.x * tiltFactor); // Tilt Body towards velocity This causes the weirdest and most consistest twitching bugs when the tilt is backwards so the object is moving backwards, maybe because im using LookRotation to look backwards?
}
velocity = Quaternion.Euler(0, transform.eulerAngles.y, 0) * velocity; // forward is always forward
cc.SimpleMove(velocity * Time.deltaTime * speed);
}
}
This script does 4 things,
get the velocity from player input.
rotate the main Object(this script) towards the velocity
add tilt towards the velocity, to the child armatureBody, this is a t Pose character in my case.
move the main Object this script is on.
Any help would be appreciated.
I tried removing the vector3 != Zero check, I tried normalizing the vectors, and I tried using a different Quaternion rotation method, but all with the same faulty results.
Check in Update() if Input.forward > threshold if so rotate to velocity. Dont rotate to velocity when only going sideways or backwards, so we can now strafe sideways and walk backwards when standing still or run and rotate to our velocity with the AD keys when running.
void Update()
{
velocity = new Vector3(Input.GetAxis("Horizontal"), 0,
Input.GetAxis("Vertical"));
if (velocity.z > 0.2f)
{
forwardVelocityThreshold = true;
}
else forwardVelocityThreshold = false;
}
Then in our FixedUpdate() we check for that bool and apply the rotateToVelocity if true.
Adjust the following if statement:
if (ccVelocity != Vector3.zero && forwardVelocityThreshold)
{
toRotation = Quaternion.LookRotation(ccVelocity, Vector3.up);
transform.rotation = Quaternion.RotateTowards(transform.rotation, toRotation, rotationSpeed * Time.fixedDeltaTime);
}
Now it works as intended, I also changed the deltaTime to FixedDeltaTime as suggested by Voidsay in the comments, although I have heard conflicting things about this. Some say FixedUpdate always uses fixedDeltaTime even if you are using deltaTime, other say no, always use fixedDeltaTime in FixedUpdate.
I have a box that fires a 2D raycast forward every few seconds, and want it to detect the player's rigidbody2D. I am able to get the raycast firing (the debug draws it correctly), but for some reason it is not detecting the player's rigidbody2D component.
void Shoot()
{
// convert this object's Rigidbody2D [_rb] rotation to radians
float rad = _rb.rotation * Mathf.Deg2Rad;
// use some math I found who-knows-where to make a Vector2 projecting forward
Vector2 firingAngle = new Vector2(Mathf.Cos(rad), Mathf.Sin(rad));
// project a 2D raycast from the position of the Rigidbody2D out to [range]
RaycastHit2D hit = Physics2D.Raycast(_rb.position, firingAngle, range);
if (hit.rigidbody != null)
{
// **This part of the code never runs, even if the player is clearly intersecting the raycast.**
Debug.DrawRay(this.transform.position, firingAngle*hit.distance, Color.yellow, 1f);
Debug.Log("Hit");
} else {
// **Instead, this part always runs.**
Debug.DrawRay(this.transform.position, firingAngle*range, Color.white, 1f);
Debug.Log("Did not hit");
}
}
Make sure when doing raycasts against GameObjects with a Rigidbody or Rigidbody2D component, that there is also a corresponding Collider or Collider2D component (either on the GameObject itself, or one of its children).
Otherwise, raycasts and collision events won't trigger.
When I'm making an object point towards another one, and try to move it with a change in velocity, the object just moves backward a little bit.
My Code:
public Rigidbody riggy;
public float speed = 100f;
public float maxSpeed = 100f;
Vector3 direction;
void Start()
{
Transform player = GameObject.Find("Von").transform;
StartCoroutine(Chase(0, player.transform));
}
void Update()
{
riggy.velocity = transform.forward * speed * Time.deltaTime; //applies velocity
}
IEnumerator Chase(float speed, Transform target) {
while (transform.position != target.position) {
var direction = (target.position - transform.position); //finds the direction of Von
var rotation = Quaternion.LookRotation(direction); // finds the rotation that the object has to move
Debug.DrawLine(transform.position, target.transform.position, Color.green);
transform.rotation = rotation; // moves the object
yield return null;
}
}
A video:
https://youtu.be/1I5bSvLBCuQ
Your script should work, so it's fault of your scene setup. Video does not show much about how your scene is made, so I can just list some possible errors:
Ensure component speed value is not negative and large enough
Rigidbody reference can be on wrong object or setup (structure) invalid
Object "Von" is not the object you want or it's origin point is somewhere else than you think
Possible there is rigidbody inside other rigidbody and this creates weird results
Additional notes:
There is no need to make additional coroutine, you could put everything inside Update and don't worry about "it might be useful if I want to make a whole new enemy", unless it gonna happen for sure. Physics manipulation should be done in FixedUpdate.
Depending what you want to do you might not need rigidbody or make them kinematic, but in the case above you are directly controlling velocity, so it would be good if you read bunny's answer here.
Last note, Time.deltaTime is time between frames inside Update(), not physics steps, read docs about Time.deltaTime and Time.fixedDeltaTime.
I'm having trouble finding my mistake regarding my automatic movement script. I will explain first what i tried to do so you can understand it better. So i am programming in c# in unity. It is for VR. I created a button, that works as a trigger when you are looking at it. When looking at the button a door goes down and the player should move inside a castle (automatically).
The door script works fine but the player is not moving at all. I used a public Vector3 where I declared the position inside the castle where the player should move to (it is only a forward direction).
Unfortunately the code looks fine to me and i cant figure it out why my player wont move :/.
So I tried playing around with the Vectors but i had no luck.
{
public float speed = 0.5f;
public Vector3 castlePosition;
private Vector3 targetPosition;
// Start is called before the first frame update
void Start()
{
targetPosition = transform.position;
}
// Update is called once per frame
void Update()
{
RaycastHit hit;
if (Physics.Raycast(transform.position, transform.forward, out hit))
{
if(hit.transform.GetComponent<DoorButton>() != null)
{
hit.transform.GetComponent<DoorButton>().OnLook();
MoveToCastle ();
}
}
transform.position = Vector3.Lerp(transform.position, targetPosition, Time.deltaTime * speed);
}
private void MoveToCastle()
{
targetPosition = castlePosition;
}
}
I was expecting that the MoveToCastle function would put my player inside the castle (at the position that I declared earlier).
Once again the OnLook function from my door is working.
Thank you in advance for your help. :)
Your MoveToCastle stops working as soon as raycast becomes false. You probably should set off some continuous process of moving to target when the raycast hits. For example start coroutine something like this:
IEnumerable MoveToCastle()
{
targetPosition = castlePosition;
while (transform.position != castlePosition) // careful here! see below
{
transform.position = Vector3.Lerp(transform.position, targetPosition, Time.deltaTime * speed);
yield return null;
}
}
Better to compare target and transform coordinates by subtracting and comparing to some small value, otherwise it can go there quite long.