I want to create a cone Gizmo like the one in the picture below by using a script.
This is an example code:
void OnDrawGizmosSelected()
{
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(transform.position, range);
}
The red line is the Gizmo that I want.
Can anyone help out?
The code below is a modified version of Tetrad's answer to a similar question.
void OnDrawGizmosSelected()
{
float angle = 30.0f;
float rayRange = 10.0f;
float halfFOV = angle / 2.0f;
float coneDirection = 180;
Quaternion upRayRotation = Quaternion.AngleAxis(-halfFOV + coneDirection, Vector3.forward);
Quaternion downRayRotation = Quaternion.AngleAxis(halfFOV + coneDirection, Vector3.forward);
Vector3 upRayDirection = upRayRotation * transform.right * rayRange;
Vector3 downRayDirection = downRayRotation * transform.right * rayRange;
Gizmos.DrawRay(transform.position, upRayDirection);
Gizmos.DrawRay(transform.position, downRayDirection);
Gizmos.DrawLine(transform.position + downRayDirection, transform.position + upRayDirection);
}
Hope that helps!
Related
Hello i am new in the forum! I hope i am in the right section! Im trying to rotate a camera (that rapresent the player POV) using the mouse delta and im rotating the camera in local coordinates not world coordinates and i want avoid gimbal lock effect. I read somewhere on the internet that for that purpose i have to use quaternions, and i read how to do that. The problem is that axis rotations works well moving in local orientation but one of the axis is losing its local orientation and it rotate following the world coordinates orientation. I will post the code and i hope someone can help me and telling me where im doing things wrong. Thanks!
public class Player : MonoBehaviour {
[Header("Camera")]
[SerializeField] private Camera _camera;
[SerializeField] private Vector2 _xMinMaxRotation = new Vector2(-90, 90);
[SerializeField] private Vector2 _yMinMaxRotation = new Vector2(-90, 90);
[SerializeField] private float _mouseXSensistivity = 1;
[SerializeField] private float _mouseYSensistivity = 1;
[SerializeField] private float _mouseZSensistivity = 1;
[SerializeField] private float _xStartRotation = 0;
[SerializeField] private float _yStartRotation = 0;
private Vector2 _mouseDelta;
private float _rotY, _rotX, _rotZ;
//public GameObject head;
// Start is called before the first frame update
void Start() {
Cursor.lockState = CursorLockMode.Locked;
}
// Update is called once per frame
void Update() {
_mouseDelta = new Vector2(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y"));
MoveCamera();
}
private void MoveCamera() {
_rotX += _mouseDelta.x * _mouseXSensistivity * Time.deltaTime * 100;
_rotX = Mathf.Clamp(_rotX, _xMinMaxRotation.x, _xMinMaxRotation.y);
_rotY += _mouseDelta.y * _mouseYSensistivity * Time.deltaTime * 100;
_rotY = Mathf.Clamp(_rotY, _yMinMaxRotation.x, _yMinMaxRotation.y);
//Calculation for RotZ
if (Input.GetKey(KeyCode.Q)) {
_rotZ += +_mouseZSensistivity * Time.deltaTime * 50;
if (_rotZ > 25) _rotZ = 25;
}
else {
if (_rotZ > 0) {
_rotZ -= 2 * _mouseZSensistivity * Time.deltaTime * 50;
if (_rotZ < 0) _rotZ = 0;
}
}
if (Input.GetKey(KeyCode.E)) {
_rotZ += -_mouseZSensistivity * Time.deltaTime * 50;
if (_rotZ < -25) _rotZ = -25;
}
else {
if (_rotZ < 0) {
_rotZ -= 2 * -_mouseZSensistivity * Time.deltaTime * 50;
if (_rotZ > 0) _rotZ = 0;
}
}
Quaternion currentRotation = Quaternion.identity;
currentRotation = currentRotation * Quaternion.AngleAxis(_rotX, transform.up);
currentRotation = currentRotation * Quaternion.AngleAxis(-_rotY, transform.right);
currentRotation = currentRotation * Quaternion.AngleAxis(_rotZ, transform.forward);
_camera.transform.localRotation = currentRotation;
//head.transform.position = _camera.transform.position;
//head.transform.rotation = _camera.transform.rotation;
}
The last part with quaternions is where im trying to calculate angles in order to properly rotate in local coordinates.
You don’t need to use quaternions at all.
You can use transform.EulerAngles instead of the transform.rotation or transform.localEulerAngles instead of transform.LocalRotation.
I messed up the capitalization I’m sure.
Say you wanted to rotate the camera 10 degrees along the local x axis. That would look something like
transform.localEulerAngles = transform.localEulerAngles.Add(10,0,0);
That’s it as far as I know. If you wanna read more about this,
transfrom.localEulerAngles
If your question was completely different, let me know and I can change or remove my answer.
I'm trying to use the Character Controller component in Unity and I managed to make the movement code, however, I was unable to add jumping and gravity or at least have them work together so my temporary solution was to just break them into 2 different methods. This probably isn't ideal so how could I get this to work properly?
void Update()
{
GetInput();
JumpingCode();
MovementCode();
}
void JumpingCode()
{
// Jumping
if (jumpPressed && characterController.isGrounded)
velocityY = Mathf.Sqrt(jumpHeight * -2f * (gravity * gravityScale));
// Gravity
velocityY += gravity * gravityScale * Time.deltaTime;
Vector3 direction = new Vector3(horizontalInput, velocityY, verticalInput).normalized;
characterController.Move(direction * walkSpeed * Time.deltaTime);
}
void MovementCode()
{
Vector3 direction = new Vector3(horizontalInput, 0f, verticalInput).normalized;
if (direction.magnitude > 0.1f)
{
float targetAngle = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg + playerCamera.eulerAngles.y;
float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVelocity, turnSmoothTime);
Vector3 moveDirection = Quaternion.Euler(0f, targetAngle, 0f) * Vector3.forward;
transform.rotation = Quaternion.Euler(0f, angle, 0f);
characterController.Move(moveDirection.normalized * walkSpeed * Time.deltaTime);
}
}
I can't understand how you're arriving at the values you're using there, but the solution would be to accumulate the outputs and then do the .Move() action once at the end, like:
void Update()
{
Vector3 motion;
GetInput();
motion += JumpingCode();
motion += MovementCode();
characterController.Move(motion*Time.deltaTime);
}
private Vector3 JumpingCode()
{
// stuff
return direction * walkSpeed;
}
private Vector3 MovementCode()
{
// stuff
return direction * walkSpeed;
}
Noteworthy there is that I dropped Time.deltaTime from your functions, but I don't know how you were using it in the code you provided.
I am trying to determine the direction of a transform. I originally tried to do this by tracking the rigidbody.velocity but that property seems unreliable so I am having to calculate the direction manually. The yellow line draws fine and it does point in the wrong direction however it appears to be delayed
I am calling the following method in my update method:
void DetermineMovementDirection()
{
currentLoc = (transform.position - prevLoc) / Time.deltaTime;
Vector3 t = (prevLoc + currentLoc).normalized;
Debug.DrawLine(transform.position, transform.position + t * 5, Color.yellow);
}
I would expect the yellow line to always point in the direction the player was moving rather than have a long delay. How can I fix this?
As requested the movement function:
void Update()
{
float inputZ = Input.GetAxis("Horizontal");
float inputX = Input.GetAxis("Vertical");
if (movementAllowed)
if (inputZ != 0 || inputX != 0)
{
transform.eulerAngles = new Vector3(0, Mathf.Atan2(inputZ, inputX) * 180 / Mathf.PI, 0);
transform.Translate(moveSpeed * inputZ * Time.deltaTime, 0f, moveSpeed * inputX * Time.deltaTime, Space.World);
}
}
And I am simply updating at the end of the update method:
prevLoc = transform.position;
have a hand of clock which the player once starts rotating (Dragging) CCW until he completes one full rotation. ( Without lifting drag )
I am trying to lock the rotation to only CCW direction while/once the player starts rotating. I got help from the following links : [Detect Direction][1] by #BobBobson108
Here is gif of what is actually happening: Demo
void OnMouseDrag()
{
//rotation
Vector3 mousePos = Input.mousePosition;
mousePos.z = 5.23f;
Vector3 objectPos = Camera.main.WorldToScreenPoint(transform.position);
mousePos.x = mousePos.x - objectPos.x;
mousePos.y = mousePos.y - objectPos.y;
angle = Mathf.Atan2(mousePos.y, mousePos.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.Euler(new Vector3(0, 0, angle - 90f));
hand_vector = transform.up;
cross_product = Vector3.Cross(ref_vector, hand_vector);
dot_product = Vector3.Dot(cross_product, transform.forward*-1);
//Debug.Log("Hand Vector: " + hand_vector);
//Debug.Log("Ref Vector: " + ref_vector);
Debug.Log(cross_product);
Debug.Log(dot_product);
}
I tried to debug the values of the cross product, but the direction of resultant vector seems to be same even when when the player starts backward rotation.
Also the cross product vector changes direction only when the player starts rotation in CW direction from the default position i.e. 12 'o clock.
I have very less experience of working with Quaternions and rotations. Any help will be highly helpful. Thanks !!!
Desired
Use http://docs.unity3d.com/ScriptReference/Vector3.Angle.html function to get the value of the angle. You should get a positive/negative value depending on the direction.
You could then lock the rotation if the sign is not the correct direction you want.
I managed to figure out a solution to above question. Here I am posting my solution in case anyone stumbles across a similar situation in future.
void OnMouseDrag()
{
transform.Rotate(new Vector3(0,0, Mathf.Sqrt(Input.GetAxis("Mouse X") * Input.GetAxis("Mouse X") + Input.GetAxis("Mouse Y") * Input.GetAxis("Mouse Y"))));
/*
Vector3 mousePos = Input.mousePosition;
mousePos.z = 5.23f;
Vector3 objectPos = Camera.main.WorldToScreenPoint(transform.position);
mousePos.x = mousePos.x - objectPos.x;
mousePos.y = mousePos.y - objectPos.y;
print("Angle is :");
print(Mathf.Atan2(mousePos.y, mousePos.x) * Mathf.Rad2Deg - 90f);
if (counter_clockwise)
{
if (Mathf.Atan2(mousePos.y, mousePos.x) * Mathf.Rad2Deg - 90f > 0)
{
angle = Mathf.Max(angle, Mathf.Atan2(mousePos.y, mousePos.x) * Mathf.Rad2Deg - 90);
transform.rotation = Quaternion.Euler(new Vector3(0, 0, angle));
}
if (Mathf.Atan2(mousePos.y, mousePos.x) * Mathf.Rad2Deg - 90f < 0)
{
angle = Mathf.Max(angle, 360 + (Mathf.Atan2(mousePos.y, mousePos.x) * Mathf.Rad2Deg - 90));
transform.rotation = Quaternion.Euler(new Vector3(0, 0, angle));
}
}
*/
glow_color.a = 1f;
child_yellowglow.color = glow_color;
}
I am setting the direction bools from using this :
void OnMouseDown()
{
Vector3 mouseDragStartPos = Input.mousePosition;
print("Mouse pos: " + mouseDragStartPos);
print(" ref_vector" + ref_vector);
if (mouseDragStartPos.x < ref_vector.x)
{
clockwise = false;
counter_clockwise = true;
print("Left !!!");
}
if (mouseDragStartPos.x >= ref_vector.x)
{
clockwise = true;
counter_clockwise = false;
print("Right !!!");
}
}
Hope this helps !!!
As you can see in the topic - I have a camera problem. I use a script (you can see below) and I have something like this - http://rapidgamesstudio.com/games/diggermachines/
What I want to achieve is a smooth following camera to player.
I've tried everything. I have about 50-60 fps and still this bug occures.
This is my camera code:
void Update() {
if(!player)
return;
//if(!isDiggableCamera) {
Vector3 point = Camera.main.WorldToViewportPoint(player.transform.position);
Vector3 delta = player.transform.position - Camera.main.ViewportToWorldPoint(new Vector3(0.5f, 0.5f, point.z)); //(new Vector3(0.5, 0.5, point.z));
Vector3 destination = transform.position + delta;
destination.z = transform.position.z;
transform.position = Vector3.SmoothDamp(transform.position, destination, ref velocity, dampTime);
//Vector3 destination = new Vector3(player.transform.position.x, player.transform.position.y, transform.position.z);
//transform.position = Vector3.SmoothDamp(transform.position, destination, ref velocity, dampTime);
//} else {
// startDigging(0, 0, 0);
//}
leftSite.position = new Vector3(leftSite.position.x, player.position.y, leftSite.position.z);
rightSite.position = new Vector3(rightSite.position.x,
player.position.y, rightSite.position.z);
}
I tried execute this code in Update(), FixedUpdate(), LateUpdate() even with all three - and still is the same problem.
Below code for updating player position:
//move player
float changableSpeedX = 5000.0f;
float changableSpeedY = 6000.0f;
Vector2 speed = new Vector2(x * Time.deltaTime * changableSpeedX,
y * Time.deltaTime * changableSpeedY);
//if(playerRigidbody.velocity.y + speed.y >= Game.game().activeMaxVelY)
// speed.y = Game.game().activeMaxVelY - playerRigidbody.velocity.y;
playerRigidbody.AddForce(speed);
//AddForce(speed);
//and checking max speed
protected void checkSpeed()
{
if(playerRigidbody.velocity.x > Game.game().activeMaxVelX)
playerRigidbody.velocity = new Vector2(Game.game().activeMaxVelX, playerRigidbody.velocity.y);
if(playerRigidbody.velocity.x < -Game.game().activeMaxVelX)
playerRigidbody.velocity = new Vector2(-Game.game().activeMaxVelX, playerRigidbody.velocity.y);
if(playerRigidbody.velocity.y > Game.game().activeMaxVelY)
playerRigidbody.velocity = new Vector2(playerRigidbody.velocity.x, Game.game().activeMaxVelY);
if(playerRigidbody.velocity.y < maxSpeedYGravity)
playerRigidbody.velocity = new Vector2(playerRigidbody.velocity.x, maxSpeedYGravity);
}
Could anyone help me?
If you need more code please let me know which part (because I don't want to add too much unnecessary code)
Might i suggest a lerp sir , in the update function use this
maincamera.transform.position = new vector3(maincamera.transform.position,player.transform.poistion,speed*Time.deltaTime);
Try This One !!!
private float xMax;
[SerializeField]
private float yMax;
[SerializeField]
private float xMin;
[SerializeField]
private float yMin;
private Transform target;
// Use this for initialization
void Start () {
target = GameObject.Find("Player").transform;
}
// Update is called once per frame
void LateUpdate () {
transform.position = new Vector3(Mathf.Clamp(target.position.x, xMin, xMax), Mathf.Clamp(target.position.y, yMin, yMax),transform.position.z);
}
}