I'd like to move my player object to click point
with constant velocity so I used MoveTowards() method but it teleports towards click point and doesn't reach the point..If it works properly I'll put walking motion in it. Please check my codes..
And I want to get advice on whether use Update() or FixedUpdate(). FixedUpdate() also doesn't wolks well. It takes mouse events not every time.
here's codes
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using System.Collections;
namespace Assets.Scripts
{
public class moveToTarget : MonoBehaviour
{
public GameObject player;
private void Awake()
{
player = GameObject.Find("player");
}
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
Vector3 clickPoint = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x,
Input.mousePosition.y, -Camera.main.transform.position.z));
Vector3 pos = player.transform.position;
Vector3 current = pos;
Vector3 desPos = new Vector3(clickPoint.x, pos.y, 0);
//I want to move object horizontally
Debug.Log(clickPoint);
player.transform.position = Vector3.MoveTowards(current, desPos, 100.0f * Time.deltaTime);
}
}
}
}
The Third input of the MoveTowards function is maxDeltaDistance. The bigger it is the faster your object will move. You are using move towards inside an If statement, which might be the cause for not reaching the target.
Related
im new to unity game development. i have to develop simple 2D object movement in square path during mouse button clicked. just simple square/circle 2D spirite move in square path during mouse clicked
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices.ComTypes;
using UnityEngine;
public class mousetomove : MonoBehaviour
{
public float speed = 5.0f;
private Transform target1;
private Transform target2;
private Transform hero ;
// Start is called before the first frame update
void Start()
{
hero = GameObject.FindGameObjectWithTag("Hero").GetComponent<Transform>();
target1 = GameObject.FindGameObjectWithTag("Player").GetComponent<Transform>();
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButton(0))
{
if (hero == target1)
{
transform.position = Vector2.MoveTowards(transform.position, target2.position ,
*Time.deltaTime);
}
}
}
}
Here you are trying to check if hero is equal to target, this will not happen I think, you have to compare positions but even doing so positions will probably not be the same but just very close. You are using MoveTowards, thats good but you have to be changing the target, like maybe have 4 targets in an array I guess
Trying to explay. I created a mirror with camera and output image from this on texture. I drop the script with transform.LookAt(target); And it`s work fine. But I want to make it work like the mirror. I mean when player look at camera, it must turn out of player on angle what player looks on mirror. I am trying to create copy of target(Transform) and change properties of this. But it unsuccessful.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MirroringAngle : MonoBehaviour
{
public Transform target;
public Transform mirror;
private Transform reflectedObject;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
Vector3 inDirection = target.transform.position;
Vector3 inNormal = new Vector3(0,0,0);
Vector3 reflectedDir = Vector3.Reflect( inDirection, inNormal);
mirror.transform.rotation = Quaternion.LookRotation(reflectedDir,
Vector3.right);
transform.LookAt(reflectedDir);
}
}
Still look at player
I think that to achieve your direction you need to reflect the players direction to the mirror.
Vector3 inDirection = targer.transform.position;
Vector3 inNormal = mirror.Transform.forward;
Vector3 reflectedDir = Vector3 Reflect(Vector3 inDirection, Vector3 inNormal);
then you can use Quaternion.LookRotation for the mirror camera or gameobject to look in that direction.
mirror.transform.rotation = Quaternion.LookRotation(reflectedDir, Vector3.up)
Edit: Find full script working:
using UnityEngine;
public class LookAtReflectedDir : MonoBehaviour
{
public Transform source;
public Transform mirror;
//private Transform reflectedObject;
// Start is called before the first frame update
void Start()
{
Vector3 inDirection = mirror.transform.position - source.transform.position;
Vector3 inNormal = mirror.forward;
Vector3 reflectedDir = Vector3.Reflect(inDirection, inNormal);
mirror.transform.rotation = Quaternion.LookRotation(reflectedDir, Vector3.up);
}
}
Mirror in normal pos:
Mirror looking to the reflected dir:
I've used a simple Unity tutorial to make a Space Invaders game, but I want to adapt it into a different game.
The tutorial made a right-and-left control of the player ship, but I changed it to rotational control (which took a while because for some reason almost no script correctly confined the rotation to the boundaries I've set).
After scripting the rotation, I wanted the shots to move forward on the screen in the direction of the axis to which it is spawned. The axis is of an empty child object inside the ship object, so its own angles are always set to 0.
I saw the original function controlling the bullet movement:
bullet.position += Vector3.up * speed;
still moves it up the screen regardless of how the bullet is rotated.
So I tried:
bullet.position += Vector3.forward * speed;
and saw it moves the bullet into the Z axis.
Basically I'm asking is whether there's a sub-function of Vector3 I'm missing which moves an object according to the direction of its own axis?
Here are the codes of the two classes:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ShotSpawner : MonoBehaviour
{
public GameObject shot;
public Transform shotSpawn;
public float fireRate;
private float nextFire;
// Start is called before the first frame update
void Start()
{
}
void Update()
{
if (Input.GetButton("Fire1") && Time.time > nextFire)
{
nextFire = Time.time + fireRate;
Instantiate(shot, shotSpawn.position, shotSpawn.rotation);
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BulletController : MonoBehaviour
{
private Transform bullet;
public float speed;
// Start is called before the first frame update
void Start()
{
bullet = GetComponent<Transform>();
}
void FixedUpdate()
{
bullet.position += Vector3.up * speed;
if (bullet.position.y >= 10)
Destroy(gameObject);
}
void OnTriggerEnter2D(Collider2D other)
{
if (other.tag == "Enemy")
{
Destroy(other.gameObject);
Destroy(gameObject);
PlayerScore.playerScore++;
}
else if (other.tag == "Base")
Destroy(gameObject);
}
}
I found the simple solution
The code required
transform.up
Rather than
Vector3.up
Transform goes by the objects axis while Vector3 goes by the world space.
This is a reduced version of the player controller I am using now, which still produces the error explained below:
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;
using UnityStandardAssets.Utility;
using Random = UnityEngine.Random;
namespace UnityStandardAssets.Characters.FirstPerson
{
[RequireComponent(typeof (CharacterController))]
public class FirstPersonController : MonoBehaviour
{
[SerializeField] private float m_RunSpeed;
private CharacterController m_CharacterController;
// Use this for initialization
private void Start()
{
m_CharacterController = GetComponent<CharacterController>();
}
private void FixedUpdate()
{
Vector3 move = Vector3.right * m_RunSpeed;
m_CharacterController.Move(move * Time.fixedDeltaTime);
}
}
}
I am using the standard assets script and I am trying to have a script teleport the player to different places. When I try and move the player it goes to that position for a frame, then goes right back to its position.
player.transform = new Vector3(1,2,3);
// works as expected, but then next frame, player's
// position is back to where it was before
This problem occurs because Move may not be able to read the up-to-date values for transform.position.
This problem has been reported on the official Unity Issue Tracker here, and a solution was posted there as well:
The problem here is that auto sync transforms is disabled in the physics settings, so characterController.Move() won't necessarily be aware of the new pose as set by the transform unless a FixedUpdate or Physics.Simulate() called happened in-between transform.position and CC.Move().
To fix that, either enable auto sync transforms in the physics settings, or sync manually via Physics.SyncTransforms right before calling Move()
So, you could fix your problem by editing FixedUpdate so that it calls Physics.SyncTransforms before Move, like this:
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;
using UnityStandardAssets.Utility;
using Random = UnityEngine.Random;
namespace UnityStandardAssets.Characters.FirstPerson
{
[RequireComponent(typeof (CharacterController))]
public class FirstPersonController : MonoBehaviour
{
[SerializeField] private float m_RunSpeed;
private CharacterController m_CharacterController;
// Use this for initialization
private void Start()
{
m_CharacterController = GetComponent<CharacterController>();
}
private void FixedUpdate()
{
Vector3 move = Vector3.right * m_RunSpeed;
Physics.SyncTransforms();
m_CharacterController.Move(move * Time.fixedDeltaTime);
}
}
}
I have tried both of these C#scripts to rotate my directional light:
using System.Collections;
using UnityEngine;
public class LightRotator : MonoBehaviour
{
void Update ()
{
transform.rotation = Quaternion.Euler(transform.eulerAngles.x + 1.0f,
transform.eulerAngles.y,
transform.eulerAngles.z);
}
}
and
using System.Collections;
using UnityEngine;
public class LightRotator : MonoBehaviour
{
void Update ()
{
transform.localEulerAngles = new Vector3(transform.localEulerAngles.x + 1.0f,
transform.localEulerAngles.y,
transform.localEulerAngles.z);
}
}
They both seem to function exactly the same: If I change transform.eulerAngles.y to transform.eulerAngles.y + 0.5f, the light will rotate along the y-axis, and the same works for the z-axis. However, when I try to do this with the x-axis, it will rotate until it hits 90º, at which point it will continue to attempt rotation but it immediately and continuously shoved back to 90º. If I reverse the direction, it does the same thing at -90º. For example, the rotation might be: 88.5,89.0,89.5,90.0, 90.5, 89.93, 90.24, 89.4, etc.
What is causing this clamping and how do I fix it?
I think this is what you are looking for: http://answers.unity3d.com/questions/187073/rotation-locks-at-90-or-270-degrees.html
In order to fix your problem, you need to use an additional vector, change it inside Update every frame, and then pass it to the eulerAngles propriety of the transform.
Vector3 vect = Vector3.zero;
float rotationSpeed = 10f;
void Start () {
vect = transform.eulerAngles; //Set the vect rotation equal to the game object's one
}
void Update ()
{
vect.x += rotationSpeed * Time.deltaTime;
//Pass unique eulerAngles representation to the object without letting Unity change it
transform.eulerAngles = vect;
}
This happens btw because there're multiple euler angles representation of a single physical rotation in the 3D space, and when you work directly on the eulerAngles propriety of the transform, Unity makes some work behind the scenes, which can lead to a gimbal lock.
Use Quaternions. It's what Unity3d uses internally and doesn't have any of the side effects of euler angles.
using System.Collections;
using UnityEngine;
public class LightRotator : MonoBehaviour
{
public Vector3 RotationAxis = Vector3.right;
Quaternion _startRotation;
float _rotationIncrement = 0;
void Start()
{
_startRotation = transform.rotation;
}
void Update ()
{
Quaternion rotationMod =
Quaternion.AngleAxis(_rotationIncrement, RotationAxis);
_rotationIncrement += 1;
transform.rotation = _startRotation * rotationMod;
}
}
However, you probably want to use something like Quaternion.RotateTowards or Quaternion.Lerp along with Time.time and a rate. You will get much smoother results that way.
if you only want to rotate along the X-axis then set the other axis as 0.