GameObject rotation based Vector2 direction - c#

I apologize in advance for my english.
I have a 2D GameObject and i want to rotate it forward based on Vector2 direction.
my arrow right now:
https://streamable.com/7kmtig
i would like this:
This code rotates arrow:
float angle = Mathf.Atan2(p.direction.y, p.direction.x) * Mathf.Rad2Deg;
punta.transform.rotation = Quaternion.AngleAxis(angle, -Vector3.forward);
punta is arrow GameObject
I created 2 scripts:
PlayerController:
using System;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public Camera cam;
Vector2 coordinate2D;
public bool direziona = false;
public Rigidbody2D rb;
public Vector2 direction;
public Vector2 mousePotion;
public float distanza;
// Start is called before the first frame update
void Start()
{
direction = Vector2.zero;
mousePotion = Vector2.zero;
distanza = 0;
rb = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(0))
{
RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero);
if (hit.collider != null)
{
direziona = true;
}
}
if (direziona)
{
mousePotion = Camera.main.ScreenToWorldPoint(Input.mousePosition);
direction = new Vector2(transform.position.x - mousePotion.x, transform.position.y - mousePotion.y).normalized;
distanza = Mathf.Clamp(Vector2.Distance(mousePotion, transform.position) * 5, 0, 12);
direction = direction * distanza;
if (Input.GetMouseButtonUp(0))
{
rb.AddForce(direction, ForceMode2D.Impulse);
direziona = false;
}
}
}
}
DragLineController:
using System.Collections;
using System.Collections.Generic;
using System.Linq.Expressions;
using TMPro;
using UnityEngine;
public class DragLineController : MonoBehaviour
{
// Start is called before the first frame update
public GameObject player;
public GameObject punta; //sprite arrow
bool ClickPlayer;
LineRenderer _lineRender;
Vector2 startPoint;
Vector2 endPoint;
PlayerController p;
void Start()
{
p = player.GetComponent<PlayerController>();
_lineRender = GetComponent<LineRenderer>();
_lineRender.SetPosition(0, Vector3.zero);
_lineRender.SetPosition(1, Vector3.zero);
}
// Update is called once per frame
void Update()
{
ClickPlayer = player.GetComponent<PlayerController>().direziona;
if (ClickPlayer)
{
startPoint = player.transform.position;
_lineRender.SetPosition(0, startPoint);
float dist =Mathf.Clamp(p.distanza,0,0.3f);
Debug.Log(dist);
endPoint = startPoint + (p.direction * dist);
_lineRender.SetPosition(1, endPoint);
Vector3 FracciaEndPoint = new Vector3(endPoint.x, endPoint.y, -1);
//punta.transform.rotation = Quaternion.LookRotation(p.direction);
punta.transform.position = FracciaEndPoint;
float angle = Mathf.Atan2(p.direction.y, p.direction.x) * Mathf.Rad2Deg;
punta.transform.rotation = Quaternion.AngleAxis(angle, -Vector3.forward);
}
else
{
_lineRender.SetPosition(0, Vector3.zero);
_lineRender.SetPosition(1, Vector3.zero);
}
}
}
Thanks in advance for your availability.

Instead of calculating the rotation for
punta.transform.rotation = Quaternion.AngleAxis(angle, -Vector3.forward);
you could instead simply assign the according axis (I assume the point looks in its Y direction)
punta.transform.up = p.direction;
or .right if instead it points in its local X direction.

Related

Unity need character to rotate to face movement direction on planetoid

we are working on a student project and we chose to do a Mario Galaxy style platformer with planetoids and gravity (kind of a big mistake for my first coding project but I cannot back out of it now) but I am having a hard time to get the character to face it's movement direction without absolutely spazzing out.
I have only been coding for around 2 months so please excuse me being useless at trying to figure this out.
This is the code I use for movement for the character
using System.Collections.Generic;
using UnityEngine;
public class SC_RigidbodyWalker : MonoBehaviour
{
public float speed = 5.0f;
public bool canJump = true;
public float jumpHeight = 2.0f;
public Camera playerCamera;
public float lookSpeed = 2.0f;
public float lookXLimit = 60.0f;
bool grounded = false;
Rigidbody r;
Vector2 rotation = Vector2.zero;
float maxVelocityChange = 10.0f;
void Awake()
{
r = GetComponent<Rigidbody>();
r.freezeRotation = true;
r.useGravity = false;
r.collisionDetectionMode = CollisionDetectionMode.ContinuousDynamic;
rotation.y = transform.eulerAngles.y;
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
void Update()
{
}
void FixedUpdate()
{
if (grounded)
{
// Calculate how fast we should be moving
Vector3 forwardDir = Vector3.Cross(transform.up, -playerCamera.transform.right).normalized;
Vector3 rightDir = Vector3.Cross(transform.up, playerCamera.transform.forward).normalized;
Vector3 targetVelocity = (forwardDir * Input.GetAxis("Vertical") + rightDir * Input.GetAxis("Horizontal")) * speed;
Vector3 velocity = transform.InverseTransformDirection(r.velocity);
velocity.y = 0;
velocity = transform.TransformDirection(velocity);
Vector3 velocityChange = transform.InverseTransformDirection(targetVelocity - velocity);
velocityChange.x = Mathf.Clamp(velocityChange.x, -maxVelocityChange, maxVelocityChange);
velocityChange.z = Mathf.Clamp(velocityChange.z, -maxVelocityChange, maxVelocityChange);
velocityChange.y = 0;
velocityChange = transform.TransformDirection(velocityChange);
r.AddForce(velocityChange, ForceMode.VelocityChange);
if (Input.GetButton("Jump") && canJump)
{
r.AddForce(transform.up * jumpHeight, ForceMode.VelocityChange);
}
}
grounded = false;
}
void OnCollisionStay()
{
grounded = true;
}
}
And here are the code for the gravity functions
using System.Collections.Generic;
using UnityEngine;
public class SC_PlanetGravity : MonoBehaviour
{
public Transform planet;
public bool alignToPlanet = true;
float gravityConstant = 9.8f;
Rigidbody r;
void Start()
{
r = GetComponent<Rigidbody>();
}
void FixedUpdate()
{
Vector3 toCenter = planet.position - transform.position;
toCenter.Normalize();
r.AddForce(toCenter * gravityConstant, ForceMode.Acceleration);
if (alignToPlanet)
{
Quaternion q = Quaternion.FromToRotation(transform.up, -toCenter);
q = q * transform.rotation;
transform.rotation = Quaternion.Slerp(transform.rotation, q, 1);
}
}
}
I can propose an alternative approach which I believe will simplify the problem, should you choose. If the root of your character is positioned at the center of the planetoid, then all movement can be handled as a rotation on root and you won't be fighting the inertia of the character or needing to orient it to the planetoid. Jumping could be handled by adding another child below the root that can slide up and down. Hope this helps!
I managed to get it working by having a new script added to the player avatar.
Here is the code, it's basically a copy paste of a part of the RigidBodyWalker script with some more added parts. It's not perfect but it works like I wanted it to.
using System.Collections.Generic;
using UnityEngine;
public class InputRotation : MonoBehaviour
{
public Camera playerCamera;
public float speed;
public float rotationSpeed;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
//float horizontalInput = Input.GetAxis("Horizontal");
//float verticalInput = Input.GetAxis("Vertical");
}
private void FixedUpdate()
{
Vector3 forwardDir = Vector3.Cross(transform.up, -playerCamera.transform.right).normalized;
Vector3 rightDir = Vector3.Cross(transform.up, playerCamera.transform.forward).normalized;
Vector3 targetVelocity = (forwardDir * Input.GetAxis("Vertical") + rightDir * Input.GetAxis("Horizontal")) * speed;
if(targetVelocity != Vector3.zero)
{
Quaternion toRotation = Quaternion.LookRotation(targetVelocity, transform.up);
transform.rotation = Quaternion.RotateTowards(transform.rotation, toRotation, rotationSpeed * Time.deltaTime);
}
}
}

change direction into random direction on collision Unity2D

I'm new to unity and I'm trying to create a game where there's a ball that can move
in the direction by dragging and releasing on the screen and that change direction randomly when hitting a prefab, I already created that kind of movement but couldn't figure out how to make the ball change direction randomly when hitting the prefab.
Sorry if this isn't the right place to ask.
Here's my script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
[SerializeField] private float power = 2;
[SerializeField] private Vector2 minPow, maxPow;
public Vector3 force;
private Vector3 startPoint, endPoint;
private Rigidbody2D rb;
private Camera cam;
private Aim aim;
void Start()
{
cam = Camera.main;
rb = GetComponent<Rigidbody2D>();
aim = GetComponent<Aim>();
}
void Update()
{
if(Input.GetMouseButtonDown(0))
{
startPoint = cam.ScreenToWorldPoint(Input.mousePosition);
startPoint.z = 15;
}
if(Input.GetMouseButton(0))
{
Vector3 currentPos = cam.ScreenToWorldPoint(Input.mousePosition);
startPoint.z = 15;
aim.RenderLine(startPoint, currentPos);
}
if(Input.GetMouseButtonUp(0))
{
endPoint = cam.ScreenToWorldPoint(Input.mousePosition);
endPoint.z = 15;
force = new Vector3(Mathf.Clamp(startPoint.x - endPoint.x, minPow.x, maxPow.x), Mathf.Clamp(startPoint.y - endPoint.y, minPow.y, maxPow.y));
rb.AddForce(force * power, ForceMode2D.Impulse);
aim.EndLine();
}
}
public void BoostUp(float pow)
{
rb.velocity *= pow;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Boost : MonoBehaviour
{
[SerializeField] float pow;
private void OnTriggerEnter2D(Collider2D other)
{
if(other.tag == "Player")
{
Player player = other.GetComponent<Player>();
if(player != null)
{
player.BoostUp(pow);
Destroy(this.gameObject);
}
}
}
}
You can get a random angle in radians using Random.Range(0f, 2f * Mathf.PI) and then pass it to Mathf.Cos and Mathf.Sin functions to get a direction with that angle:
float angle = Random.Range( 0f, 2f * Mathf.PI );
Vector2 direction = new Vector2( Mathf.Cos( angle ), Mathf.Sin( angle ) );

My player rotation influnce my movement joystick how i fix this?

I crate a joystick and I calculate the direction the joystick make then with my direction I calculate my angle when I calculate my angle I duplicate my script so now one joystick for moving in script one and one joystick are for rotation in script 2, my problem is that when I rotate my player, let's say 90 degrees my move joystick moves the player to a different direction
The move joystick code have the angle calculate
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using Unity.Mathematics;
using UnityEditor;
using UnityEditor.Experimental.GraphView;
using UnityEngine;
public class joystick : MonoBehaviour
{
public Transform player;
public float speed;
private bool touchStart = false;
private Vector2 pointA;
private Vector2 pointB;
public Transform circle;
public Transform outerCircle;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
Debug.Log(Input.mousePosition.x);
if (Input.GetMouseButtonDown(0))
{
if (Input.mousePosition.x < Screen.width / 2)
{
pointA = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, Camera.main.transform.position.z));
circle.GetComponent<SpriteRenderer>().enabled = true;
outerCircle.GetComponent<SpriteRenderer>().enabled = true;
circle.transform.position = pointA;
outerCircle.transform.position = pointA;
}
}
if (Input.GetMouseButton(0))
{
if (Input.mousePosition.x < Screen.width / 2)
{
pointB = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, Camera.main.transform.position.z));
touchStart = true;
}
}
else
{
touchStart = false;
circle.GetComponent<SpriteRenderer>().enabled = false;
outerCircle.GetComponent<SpriteRenderer>().enabled = false;
}
}
private void FixedUpdate()
{
if (touchStart)
{
if (Input.mousePosition.x < Screen.width/2)
{
Vector2 offset = pointB - pointA;
Vector2 direction = Vector3.ClampMagnitude(offset, 1.0f);
float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg - 90;
Quaternion angleAxis = Quaternion.AngleAxis(angle, Vector3.forward);
movePlayer(direction);
circle.transform.position = new Vector2(pointA.x + direction.x, pointA.y + direction.y);
}
}
}
void movePlayer(Vector2 direction)
{
player.Translate(direction + player.rotation) * speed * Time.deltaTime);
}
}

Is There A Way To Use The Axes Input From A Joystick To Rotate A GameObject Around A Point?

I have a gun and a player (cube) on a 2d Unity Project. I have made a script that rotates the gun around the player depending on the position of the mouse on the screen. I was wondering if I could adapt this script to make the gun rotate depending on the Horizontal and Vertical values of a joystick?
this is what I have so far (don't worry about my terrible spelling):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class WeaponAming : MonoBehaviour
{
public GameObject bullet;
public GameObject spawn;
public ParticleSystem mf1;
public ParticleSystem mf2;
public float speed = .5f;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
turning();
if (Input.GetButtonDown("XButton"))
{
shoot();
}
}
void turning()
{
Vector3 mousePos = Input.mousePosition;
mousePos.z = 10;
mousePos = Camera.main.ScreenToWorldPoint(mousePos);
Vector2 direc = new Vector2(mousePos.x - transform.position.x, mousePos.y - transform.position.y);
transform.right = direc;
}
void shoot()
{
mf1.Play();
mf2.Play();
GameObject projectile = (GameObject)Instantiate(bullet, spawn.transform.position, Quaternion.identity);
projectile.transform.right = transform.right;
}
}
You can make a direction from Input.GetAxisRaw("Horizontal") and Input.GetAxisRaw("Horizontal") if at least one is nonzero, and then set the transform's right to that direction:
void turning()
{
float horiz = Input.GetAxisRaw("Horizontal");
float vert = Input.GetAxisRaw("Vertical");
if (horiz != 0 || vert != 0)
{
Vector2 direc = new Vector2(horiz, vert);
transform.right = direc;
}
}
If you would like to invert the controls vertically, negate vert:
void turning()
{
float horiz = Input.GetAxisRaw("Horizontal");
float vert = Input.GetAxisRaw("Vertical");
if (horiz != 0 || vert != 0)
{
Vector2 direc = new Vector2(horiz, -vert);
transform.right = direc;
}
}

Move Camera in UnityScript 2d in C#

I have just started programming Unity 2d, and I have faced one large problem: How do I move the camera? The script is attached to the object "player". I want it to move with the player. Thanks!
/*
I
*/
using UnityEngine;
using System.Collections;
public class PlayerController : MonoBehaviour
{
public float speed = 10; //Float for speed
public string hAxis = "Horizontal";
void Start ()
{
//empty
}
void FixedUpdate ()
{
if (Input.GetAxis (hAxis) < 0) //Left
{
Vector3 newScale = transform.localScale;
newScale.y = 1.0f;
newScale.x = 1.0f;
transform.localScale = newScale;
}
else if (Input.GetAxis (hAxis) > 0) //Right
{
Vector3 newScale =transform.localScale;
newScale.x = 1.0f;
transform.localScale = newScale;
}
//Position transformation
transform.position = transform.position + transform.right * Input.GetAxis(axisName) * speed * Time.deltaTime;
}
}
Without any scripts, you could just drag the Camera GameObject to be a child of the player and the camera would start following the player position.
For a script, try this, set player as the target.
using UnityEngine;
using System.Collections;
public class SmoothCamera2D : MonoBehaviour {
public float dampTime = 0.15f;
private Vector3 velocity = Vector3.zero;
public Transform target;
// Update is called once per frame
void Update ()
{
if (target)
{
Vector3 point = camera.WorldToViewportPoint(target.position);
Vector3 delta = target.position - camera.ViewportToWorldPoint(new Vector3(0.5f, 0.5f, point.z)); //(new Vector3(0.5, 0.5, point.z));
Vector3 destination = transform.position + delta;
transform.position = Vector3.SmoothDamp(transform.position, destination, ref velocity, dampTime);
}
}
}

Categories