How to rotate an object towards where the mouse is in Unity? - c#

I have a little problem with the player.
I've implemented a code that makes the object move slowly toward the mouse's position.
The problem: That the object does not rotate, I want it to rotate, to be pointed towards the mouse.
private Vector3 _target;
public Camera Camera;
public bool FollowMouse;
public bool ShipAccelerates;
public float ShipSpeed = 2.0f;
public void OnEnable()
{
if (Camera == null)
{
throw new InvalidOperationException("Camera not set");
}
}
public void Update()
{
if (FollowMouse || Input.GetMouseButton(0))
{
_target = Camera.ScreenToWorldPoint(Input.mousePosition);
_target.z = 0;
}
var delta = ShipSpeed * Time.deltaTime;
if (ShipAccelerates)
{
delta *= Vector3.Distance(transform.position, _target);
}
transform.position = Vector3.MoveTowards(transform.position, _target, delta);
}
I would be grateful if someone would help me.
Thanks!

Related

Bullet Impact force not working as intended

When I shoot my bullet on a rigid body, it just moves in the wrong direction (to the right, when it is supposed to go forward) Here is the script that handle bullet and target interactions.
I have no idea why this isn't working and help would be appreciated.
thx
using UnityEngine;
public class Gun : MonoBehaviour
{
public float damage = 10f;
public float range = 100f;
public float fireRate = 15f;
public float impactForce = 200f;
public ParticleSystem muzzleFlash;
private float nextTimeToFire = 0f;
public Camera fpsCam;
// Update is called once per frame
void Update()
{
if (Input.GetButton("Fire1") && Time.time >= nextTimeToFire)
{
nextTimeToFire = Time.time + 1f / fireRate;
Shoot();
}
}
void Shoot()
{
muzzleFlash.Play();
RaycastHit hit;
if (Physics.Raycast(fpsCam.transform.position, fpsCam.transform.forward, out hit, range))
{
Target target = hit.transform.GetComponent<Target>();
if (target != null)
{
target.TakeDamage(damage);
hit.rigidbody.AddForceAtPosition(transform.forward * impactForce, hit.point);
}
}
}
}
You're using the wrong transform to get the forward vector from.
if (target != null)
{
target.TakeDamage(damage);
hit.rigidbody.AddForceAtPosition(transform.forward * impactForce, hit.point);
}
should be:
if (target != null)
{
target.TakeDamage(damage);
hit.rigidbody.AddForceAtPosition(fpsCam.transform.forward * impactForce, hit.point);
}

Unity how to "power bounce" one object from another relative to it's angle?

I'm working on a simple 3D game where some balls (fixed Z position) fall along a path (using gravity and physics material) to a small flat platform and "power bounce" off this platform. The player can rotate this platform so I want to recreate a realistic bounce direction according to the platform's angle.
I'm new to coding but so far I've figured the relationship between the vector of the ball as it comes into collision with the platform and the platform's normal, which should be a perpendicular line from the surface and that can be used to reflect the ball's vector to the other direction.
I already used OnCollisionEnter and if statement to detect whether it's the platform you are colliding with, but I don't understand where to indicate the normal of the surface and how to access it. Should it be as a public class in the other object or can it be detected from the ball game object?
I tried some examples from this and other websites and got this far:
public class OnCollision : MonoBehaviour
{
public float speed = 25f;
public Rigidbody rb;
private Rigidbody rigid;
private void Start()
{
rigid = transform.GetComponent<Rigidbody>();
}
private void OnCollisionEnter(Collision collision)
{
if (collision.transform.tag == "BouncePad") {
rb.velocity = transform.up * speed;
}
}
}
Now it bounces off vertically, so I'm guessing I should change the code where the transform.up * speed part is.
Could anyone guide me, please?
Much appreciated.
If you are already using Physics material, look into the Bounciness property. A value of 0 means no bounce, a value of 1 will lead to no loss of energy. The angle of the bounce will be calculated for you. Make sure you drag the physics material onto each object-- both the ball and the wall's material will have an effect.
Finally somebody gave me a hand and came to this solution:
public class Bounce : MonoBehaviour
{
public Rigidbody rb;
public float str = 0.21f;
public float str2 = 0.15f;
// Start is called before the first frame update
private void Start()
{
rb = GetComponent<Rigidbody>();
}
private void OnCollisionEnter(Collision col)
{
if (col.gameObject.tag == "BouncePad")
{
rb.AddForce(rb.velocity * str, ForceMode.Impulse);
}
if (col.gameObject.tag == "BouncePad2")
{
rb.AddForce(rb.velocity * str2, ForceMode.Impulse);
}
}
// Update is called once per frame
void Update()
{
}
}
public class BouncTest : MonoBehaviour
{
[SerializeField] private float hight = 3;
[SerializeField] private int times = 5;
[SerializeField] private float speed = 8;
private Vector3 _startPos;
private bool _checkUP;
private int _countTimes;
private float _hightbuf;
[HideInInspector]
public bool _bounceEnd;
private void Awake()
{
_startPos = transform.position;
}
public void TurnOnBounceEffect()
{
_bounceEnd = true;
_checkUP = false;
_hightbuf = hight;
_countTimes = 0;
}
private void FixedUpdate()
{
BounceEffect();
}
private void BounceEffect()
{
if (_bounceEnd)
{
if (!_checkUP)
{
if (transform.position.y <= (_startPos.y + _hightbuf))
transform.position = Vector2.MoveTowards(transform.position, new Vector2(_startPos.x, transform.position.y) + (Vector2.up * _hightbuf), speed * Time.fixedDeltaTime);
else
{
_checkUP = true;
}
}
else if (times != _countTimes)
{
if (transform.position.y > _startPos.y)
transform.position = Vector2.MoveTowards(transform.position, _startPos, speed * Time.fixedDeltaTime);
else
{
_countTimes++;
_checkUP = false;
_hightbuf /= 2;
}
}
else
{
transform.position = Vector2.MoveTowards(transform.position, _startPos, speed * Time.fixedDeltaTime);
if (transform.position.y <= _startPos.y)
{
_bounceEnd = false;
}
}
}
}
}

Unity: issue with joystick

For the third day I'm suffering with the control for a mobile game. I want to implement control via the joystick.
I want such control in the game as in Color Road - https://vk.com/video174341022_456239047
And I did this here (via joystick) - https://vk.com/video174341022_456239048
The difference is that in the game Color Road hamburger can be kept in the center without any strain, it is very convenient from the edge of the screen to go to the center. In my control to keep in the center of the screen you need to make a lot of effort, because if you push the joystick slightly more to the left, the triangle flies to the edge of the screen, and if you do not let the joystick go to the left, it will move at the speed of the turtle.
My joystick code:
public class VirtualJoystick : MonoBehaviour, IDragHandler, IPointerUpHandler, IPointerDownHandler {
private Image backgroundImage;
private Image joystickImage;
private Vector3 inputVector;
private void Start()
{
backgroundImage = GetComponent<Image>();
joystickImage = transform.GetChild(0).GetComponent<Image>();
}
public virtual void OnDrag(PointerEventData eventData)
{
Vector2 pos;
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(backgroundImage.rectTransform, eventData.position,
eventData.pressEventCamera, out pos))
{
pos.x = (pos.x / (backgroundImage.rectTransform.sizeDelta.x));
//pos.y = (pos.y / backgroundImage.rectTransform.sizeDelta.y);
inputVector = new Vector3(pos.x * 2f, 0, 0);
inputVector = (inputVector.magnitude > 1.0f) ? inputVector.normalized : inputVector;
joystickImage.rectTransform.anchoredPosition = new Vector3(inputVector.x * (backgroundImage.rectTransform.sizeDelta.x / 2),
inputVector.z * inputVector.y);
}
}
public virtual void OnPointerDown(PointerEventData eventData)
{
OnDrag(eventData);
}
public virtual void OnPointerUp(PointerEventData eventData)
{
inputVector = Vector3.zero;
joystickImage.rectTransform.anchoredPosition = Vector3.zero;
}
public float Horizontal()
{
if (inputVector.x != 0)
{
return inputVector.x;
}
else
{
return Input.GetAxis("Horizontal");
}
}
}
Control triangle:
public class PlayerMover : MonoBehaviour {
public VirtualJoystick joystick;
private Vector3 MoveVector;
private Rigidbody2D rigidbody;
public float moveSpeed = 10;
void Start()
{
rigidbody = gameObject.GetComponent<Rigidbody2D>();
}
void Update()
{
MoveVector = PoolInput();
Move();
}
private void Move()
{
rigidbody.velocity = Vector2.zero;
rigidbody.velocity = ((MoveVector * moveSpeed));
}
private Vector3 PoolInput()
{
Vector3 dir = Vector3.zero;
dir.x = joystick.Horizontal();
dir.y = 0;
dir.z = 0;
if (dir.magnitude > 1)
dir.Normalize();
Debug.Log("Dir = " + dir);
return dir;
}
}
I can not find any info to fix this. Everywhere the same tutorials. Maybe it's something else you need to implement? Not through the joystick? What is the problem with such a wooden control for me?
P.S Sorry for my bad english

Unity: animation not working

I'm building an android game in which the player is controlled using Simple joystick plugin. When I am controlling the player using Keyboard the player animations work but when I control it using the joystick ui button the walk animation does not trigger even when the player is moving.Following are the codes used.
Player movement
using UnityEngine;
using UnityEngine.UI;
namespace CompleteProject
{
public class PlayerMovement : MonoBehaviour
{
public float speed = 6f; // The speed that the player will move at.
public Text teleportText;
public GameObject teleportCanvas;
public GameObject teleOptionCanvas;
Vector3 movement; // The vector to store the direction of the player's movement.
Animator anim; // Reference to the animator component.
Rigidbody playerRigidbody; // Reference to the player's rigidbody.
int floorMask; // A layer mask so that a ray can be cast just at gameobjects on the floor layer.
float camRayLength = 100f; // The length of the ray from the camera into the scene.
void Awake ()
{
// Create a layer mask for the floor layer.
floorMask = LayerMask.GetMask ("Floor");
// Set up references.
anim = GetComponent <Animator> ();
playerRigidbody = GetComponent <Rigidbody> ();
}
void FixedUpdate ()
{
// Store the input axes.
float h = Input.GetAxisRaw ("Horizontal");
float v = Input.GetAxisRaw ("Vertical");
// Move the player around the scene.
Move (h, v);
// Turn the player to face the mouse cursor.
Turning ();
// Animate the player.
Animating (h, v);
}
void Move (float h, float v)
{
// Set the movement vector based on the axis input.
movement.Set (h, 0f, v);
// Normalise the movement vector and make it proportional to the speed per second.
movement = movement.normalized * speed * Time.deltaTime;
// Move the player to it's current position plus the movement.
playerRigidbody.MovePosition (transform.position + movement);
}
void Turning ()
{
// Create a ray from the mouse cursor on screen in the direction of the camera.
Ray camRay = Camera.main.ScreenPointToRay (Input.mousePosition);
// Create a RaycastHit variable to store information about what was hit by the ray.
RaycastHit floorHit;
// Perform the raycast and if it hits something on the floor layer...
if(Physics.Raycast (camRay, out floorHit, camRayLength, floorMask))
{
// Create a vector from the player to the point on the floor the raycast from the mouse hit.
Vector3 playerToMouse = floorHit.point - transform.position;
// Ensure the vector is entirely along the floor plane.
playerToMouse.y = 0f;
// Create a quaternion (rotation) based on looking down the vector from the player to the mouse.
Quaternion newRotation = Quaternion.LookRotation (playerToMouse);
// Set the player's rotation to this new rotation.
playerRigidbody.MoveRotation (newRotation);
}
}
void Animating (float h, float v)
{
// Create a boolean that is true if either of the input axes is non-zero.
bool walking = h != 0f || v != 0f;
// Tell the animator whether or not the player is walking.
anim.SetBool ("IsWalking", walking);
}
void OnTriggerEnter(Collider col)
{
if (col.tag == "Teleport")
{
teleportCanvas.SetActive (true);
if (ScoreManager.score < 200)
teleportText.text = "SORRY!! ATLEAST 200 POINTS REQUIRED";
else if (ScoreManager.score >= 200)
{
teleportText.text = "READY TO GO!!";
teleOptionCanvas.SetActive (true);
}
}
}
void OnTriggerStay(Collider col)
{
if(col.tag == "Teleport")
Time.timeScale = 0.6f;
}
void OnTriggerExit(Collider col)
{
if (col.tag == "Teleport")
{
Time.timeScale = 1f;
teleportCanvas.SetActive (false);
teleOptionCanvas.SetActive (false);
}
}
}
}
Joystick control
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
namespace GeekGame.Input{
public class JoystickMove : MonoBehaviour ,IDragHandler,IEndDragHandler
{
// remember turning is with joystick rotate
// calculate the h and the v, then give it to PlayerMovement
Animator anim;
public static JoystickMove instance=null;
public float _speed=6f;
[Tooltip("the joystick radius ")]
public float R=90f;
private float _r;
private Vector2 centerPos;
private float _h;
private float _v;
public float H{
get{return _h;}
}
public float V{
get{return _v;}
}
void Awake(){
if(instance!=null){
Destroy(this.gameObject);
}else{
instance=this;
}
}
void Start(){
_r=1f*Screen.width/960f*R; //this to calculate the scale of screen
centerPos=GetComponent<RectTransform>().position;
}
void SetHAndF(Vector2 pos){ //Horizontall and Vertical axes
Vector2 diff=pos-centerPos;
float distance=diff.magnitude;
if(distance>_r){
pos=centerPos+diff/distance*_r;
}
GetComponent<RectTransform>().position=pos;
Vector2 move=pos-centerPos;
_h=move.x;
_v=move.y;
}
public void OnDrag(PointerEventData data)
{
Vector2 newPos =new Vector2(data.position.x-20f,data.position.y-20f);
//clamp the sprite
SetHAndF(newPos);
}
public void OnEndDrag(PointerEventData data){
Debug.Log("End Drag"+centerPos);
GetComponent<RectTransform>().position=centerPos;
SetHAndF(centerPos);
}
}
}
Fixed by adding the animating function in Joystickmovement and calling it in update.
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
namespace GeekGame.Input{
public class JoystickMove : MonoBehaviour ,IDragHandler,IEndDragHandler
{
// remember turning is with joystick rotate
// calculate the h and the v, then give it to PlayerMovement
public static JoystickMove instance=null;
public float _speed=6f;
public GameObject player;
public Animator animate;
bool walking;
[Tooltip("the joystick radius ")]
public float R=90f;
private float _r;
private Vector2 centerPos;
private float _h;
private float _v;
public float H{
get{return _h;}
}
public float V{
get{return _v;}
}
void Awake(){
if(instance!=null){
Destroy(this.gameObject);
}else{
instance=this;
}
animate = player.GetComponent<Animator> ();
}
void Start(){
_r=1f*Screen.width/960f*R; //this to calculate the scale of screen
centerPos=GetComponent<RectTransform>().position;
}
void Update()
{
Animating (_h, _v);
}
void SetHAndF(Vector2 pos){ //Horizontall and Vertical axes
Vector2 diff=pos-centerPos;
float distance=diff.magnitude;
if(distance>_r){
pos=centerPos+diff/distance*_r;
}
GetComponent<RectTransform>().position=pos;
Vector2 move=pos-centerPos;
_h=move.x;
_v=move.y;
}
public void OnDrag(PointerEventData data)
{
Vector2 newPos =new Vector2(data.position.x-20f,data.position.y-20f);
//clamp the sprite
SetHAndF(newPos);
Animating (_h, _v);
}
public void OnEndDrag(PointerEventData data){
Debug.Log("End Drag"+centerPos);
GetComponent<RectTransform>().position=centerPos;
SetHAndF(centerPos);
}
void Animating (float h, float v)
{
// Create a boolean that is true if either of the input axes is non-zero.
bool walking = h != 0f || v != 0f;
// Tell the animator whether or not the player is walking.
animate.SetBool ("IsWalking", walking);
}
}
}

how to shoot in the mouse pointer angle?

I have a player which is shooting with bullets to the enemy,the bullets are moving towards the right,in a correct angle,but my bullet is not pointing towards that angle,the bullets is unable to change its angle.,how to change it?,it should not only move in that angle but also point towards it,currently i am transforming it to right of the screen.,the enemy are spawning from the right.here is my code for movement and transformation,any help thanx,
this is the code for direction,and for the shooting rate
using UnityEngine;
using System.Collections;
public class WeaponScript : MonoBehaviour
{
public Transform shotPrefab;
public float shootingRate = 0.25f;
private float shootCooldown;
void Start()
{
shootCooldown = 0f;
}
void Update()
{
if (shootCooldown > 0)
{
shootCooldown -= Time.deltaTime;
}
}
public void Attack(bool isEnemy)
{
if (CanAttack)
{
shootCooldown = shootingRate;
// Create a new shot
var shotTransform = Instantiate(shotPrefab) as Transform;
// Assign position
shotTransform.position = transform.position;
// The is enemy property
ShotScript shot = shotTransform.gameObject.GetComponent<ShotScript>();
if (shot != null)
{
shot.isEnemyShot = isEnemy;
}
// Make the weapon shot always towards it
MoveScript move = shotTransform.gameObject.GetComponent<MoveScript>();
if (move != null)
{
move.direction = this.transform.right;
}
}
}
public bool CanAttack
{
get
{
return shootCooldown <= 0f;
}
}
}
this is the code for movement
using UnityEngine;
using System.Collections;
public class MoveScript : MonoBehaviour {
public Vector2 speed = new Vector2(10,10);
public Vector2 direction = new Vector2(1,0);
void Update () {
Vector3 movement = new Vector3 (speed.x * direction.x, speed.y * direction.y, 0);
movement *= Time.deltaTime;
transform.Translate(movement);
}
}
Using transform.LookAt(transform.position + direction) will immediately point your object in the specified direction.

Categories