I have this following particular code to flick an object forward by swiping in the direction that i want. The issue is that my camera angle is rotated so whenever i flick the object to the center or left, the flick isnt accurate. When i flick anywhere to the right, the object is thrown precisely. How can i adjust this code so that the object is throw to the world space direction regardless of camera rotation please. Thanks.
Code:`public class SwipeScript : MonoBehaviour
{
public float force = 2f;
public bool isTarget = false;
public float zFactor = 2f;
public Vector3 startPosition;
private Vector2 startSwipe;
private Vector2 endSwipe;
private Rigidbody currentBoxRb;
void Start()
{
currentBoxRb = StackerManager.currentBox.GetComponent<Rigidbody>();
startPosition = new Vector3(transform.position.x, transform.position.y, transform.position.z);
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
startSwipe = Camera.main.ScreenToViewportPoint(Input.mousePosition);
}
if (Input.GetMouseButtonUp(0))
{
endSwipe = Camera.main.ScreenToViewportPoint(Input.mousePosition);
if (isTarget == true)
{
Swipe();
isTarget = false;
}
}
}
void Swipe()
{
Vector3 swipe = endSwipe - startSwipe;
swipe.z = swipe.y / zFactor;
swipe.y = -0.001f;
currentBoxRb.isKinematic = false;
currentBoxRb.AddForce(swipe * force, ForceMode.Impulse);
}
private void OnMouseDown()
{
currentBoxRb.constraints = RigidbodyConstraints.None;
isTarget = true;
}
}
Related
I'm having hard time figuring out how to make a dragged object always appear in front of other objects. To goal is to be able to place the sphere (or any other object) on top of the other blocks.
I have the following script to illustrate my problem.
What obvious thing am I missing here ? Should I be continuously checking what's behind and move the object in front ? I think I'm lost here ... if anyone could point me on the right track.
using UnityEngine;
public class MouseDrag : MonoBehaviour
{
private Vector3 mOffset;
private float mZCoord;
private Transform tr;
private Camera mainCamera;
[SerializeField] private Vector3 gridSize = new Vector3(4f, 3f, 4f);
private void Awake()
{
if (mainCamera == null) mainCamera = Camera.main;
tr = transform;
}
private void OnMouseDown()
{
var position = tr.position;
mZCoord = mainCamera.WorldToScreenPoint(position).z;
mOffset = position - GetMouseAsWorldPoint();
}
private Vector3 GetMouseAsWorldPoint()
{
var mousePoint = Input.mousePosition;
mousePoint.z = mZCoord;
return mainCamera.ScreenToWorldPoint(mousePoint);
}
private void OnMouseDrag()
{
transform.position = GetMouseAsWorldPoint() + mOffset;
}
private void OnMouseUp()
{
var pos = tr.position;
transform.position = new Vector3(
Mathf.RoundToInt(pos.x) / gridSize.x * gridSize.x,
Mathf.RoundToInt(pos.y) / gridSize.y * gridSize.y,
Mathf.RoundToInt(pos.z) / gridSize.z * gridSize.z);
}
}
I am new to game development, i am trying to to change my code to mobile touch. I tried to change the flowing code to make workable for mobile touchscreen unfortunately failed. can you help me how can I make flowing code for mobile?
Here is the code.
Vector2 newPos;
bool canMove = true;
private void Start()
{
rb = GetComponent<Rigidbody2D>();
newPos = transform.position;
}
private void Update()
{
if (canMove)
{
if (Input.GetKeyDown(KeyCode.RightArrow))
{
newPos.x += 1.4f;
transform.position = newPos;
}
if (Input.GetKeyDown(KeyCode.LeftArrow))
{
newPos.x -= 1.4f;
transform.position = newPos;
}
}
if (Input.GetKeyDown(KeyCode.Space) && canMove)
{
rb.AddForce(Vector3.down * speed);
canMove = false;
}
Vector2 clampPos = transform.position;
clampPos.x = Mathf.Clamp(transform.position.x, -2.1f, 2.1f);
transform.position = clampPos;
}
Create a Canvas with a screen wide transparent Image component inside.
Use OnPointerDown and OnDrag event functions to catch finger movement on this image. Just make your class implement IPointerDownHandler and IDragHandler interfaces and use PointerEventData args properties to get delta or current position.
You can use the code below. Add it to the screen wide image and assign your Ridigbody2d and transform in inspector.
public class Movement: MonoBehaviour, IPointerDownHandler, IDragHandler
{
public Rigidbody2d rb;
public float maxSpeed = 10f;
public float sensitivity = 0.1f;
public float xBound = 2.1f;
Vector3 initialFingerPosition;
bool canMove = true;
public void OnPointerDown(PointerEventData pointerEventData)
{
initialFingerPosition = pointerEventData.position;
}
public void OnDrag(PointerEventData data)
{
if(!canMove)
return;
var position = rb.position;
position += data.delta * sensitivity * speed * Time.deltaTime;
position.x = Mathf.Clamp(position.x, -xBound, xBound);
rb.MovePosition(position);
}
}
Hello everyone and thanks in advance for your answers!
I am a beginner in unity, coding my second game after i finshed a couple of tutorials.
Since today, i noticed that suddenly all my "GameObjects" have a "UnityEngine." in front of them.
I have no idea how that happened, and it is also not just in one script, but all of them. Heres an example of it:
UnityEngine.GameObject item = (UnityEngine.GameObject)Instantiate(itemGOList[i], spawnTransform, spawnRotation);
This worked fine before without the "UnityEngine.", but now it only works when its written this way.
Do you know how this could have happened and how to revert it?
This is one of the scripts:
using UnityEngine;
using UnityEngine.EventSystems;
public class Turret : MonoBehaviour
{
private Transform target;
private Enemy targetEnemy;
[Header("General")]
public float range = 10f;
[Header("Use Bullets/missiles (default)")]
public UnityEngine.GameObject bulletPrefab;
public float fireRate = 1f;
private float fireCountdown = 0f;
public AudioClip shootingSound;
private AudioSource audioSource;
[Header("Use Laser (default)")]
public bool useLaser = false;
public int damageOverTime = 20;
public float slowAmount = .5f;
public LineRenderer lineRenderer;
public ParticleSystem impactEffect;
public Light impactLight;
[Header("Unity Setup Fields")]
public string enemyTag = "Enemy";
public Transform partToRotate;
public float turnSpeed = 10f;
public Transform firePoint;
void Start()
{
InvokeRepeating(nameof(UpdateTarget), 0f, 0.3f); // Call the UpdateTarget Method after 0 seconds, then repeat every 0.3 seconds.
audioSource = GetComponent<AudioSource>(); //Puts the AudioSource of this GO (the turret) into the variable audioSource.
}
void UpdateTarget ()
{
UnityEngine.GameObject[] enemies = UnityEngine.GameObject.FindGameObjectsWithTag(enemyTag); // Find all enemies (and store in a list?).
float shortestDistance = Mathf.Infinity; // Create a float for the shortest distance to an enemy.
UnityEngine.GameObject nearestEnemy = null; // Create a variable which stores the nearest enemy as a gameobject.
foreach (UnityEngine.GameObject enemy in enemies) // Loop through the enemies array.
{
float distanceToEnemy = Vector3.Distance(transform.position, enemy.transform.position); //Get the distance to each enemy and stores it.
if (distanceToEnemy < shortestDistance) // If any of the enemies is closer than the original, make this distance the new shortestDistance and the new enemy to the nearestEnemy.
{
shortestDistance = distanceToEnemy;
nearestEnemy = enemy;
}
}
if (nearestEnemy != null && shortestDistance <= range) // Sets the target to the nearestEnemy (only if its in range and not null).
{
target = nearestEnemy.transform;
targetEnemy = nearestEnemy.GetComponent<Enemy>();
}
else
{
target = null;
}
}
void Update()
{
if (target == null) // If there is no target, do nothing.
{
if (useLaser)
{
if (lineRenderer.enabled)
{
lineRenderer.enabled = false;
impactEffect.Stop();
impactLight.enabled = false;
audioSource.Stop();
}
}
return;
}
LockOnTarget();
if (useLaser)
{
Laser();
}
else
{
if (fireCountdown <= 0f)
{
Shoot();
fireCountdown = 1f / fireRate;
}
fireCountdown -= Time.deltaTime;
}
}
void Laser()
{
targetEnemy.TakeDamage(damageOverTime * Time.deltaTime);
targetEnemy.Slow(slowAmount);
if (!lineRenderer.enabled)
{
lineRenderer.enabled = true;
impactEffect.Play();
impactLight.enabled = true;
if (audioSource.isPlaying == false)
{
audioSource.Play();
}
}
lineRenderer.SetPosition(0, firePoint.position);
lineRenderer.SetPosition(1, target.position);
Vector3 dir = firePoint.position - target.position;
impactEffect.transform.position = target.position + dir.normalized * 1f;
impactEffect.transform.rotation = Quaternion.LookRotation(dir);
}
void LockOnTarget()
{
Vector3 dir = target.position - transform.position; // Store the direction from turret to target.
Quaternion lookRotation = Quaternion.LookRotation(dir); // I have no idea how this works...
Vector3 rotation = Quaternion.Lerp(partToRotate.rotation, lookRotation, Time.deltaTime * turnSpeed).eulerAngles; // Convert quaternion angles to euler angles and Lerp it (smoothing out the transition).
partToRotate.rotation = Quaternion.Euler(0f, rotation.y, 0f); // Only rotate around the y-axis.
}
void Shoot()
{
UnityEngine.GameObject bulletGO = (UnityEngine.GameObject)Instantiate(bulletPrefab, firePoint.position, firePoint.rotation); // Spawn a bullet at the location and rotation of firePoint. (Also makes this a GO to reference it.
Bullet bullet = bulletGO.GetComponent<Bullet>(); // I have no idea how this works...
audioSource.PlayOneShot(shootingSound, 0.2f);
if (bullet != null) // If there is a bullet, use the seek method from the bullet script.
{
bullet.Seek(target);
}
}
void OnDrawGizmosSelected() // Do this method if gizmo is selected.
{
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(transform.position, range); // Draw a wire sphere on the selected point (selected turret f. e.) and give it the towers range.
}
}
The problem was that i had a script called "GameObject" in my Unity Project.
I was also able to rename all "UnityEngine.GameObject" to "Gameobject" by using the Quick Action in Visual Studio.
I created an 3dobject and set a game object as target, and added the below code to main camera. I am able to zoom into the 3d object, but im not able to zoom out of it. How to zoom out? i.e to go back to original position.
using System.Collections;
using UnityEngine;
public class zoo22 : MonoBehaviour
{
public float movespeed = 35.0f;
//you need to say how far from the object the camera will stop
public float minimumDistanceFromTarget = 5f;
public GameObject targetobject;
private bool movingtowardstarget = false;
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(1))
{
if (movingtowardstarget == true)
{
movingtowardstarget = false;
}
else
{
movingtowardstarget = true;
}
}
if (movingtowardstarget)
{
movetowardstarget(targetobject);
}
}
public void movetowardstarget(GameObject target)
{
if(Vector3.Distance(transform.position, target.transform.position) > minimumDistanceFromTarget) //we move only if we are further than the minimum distance
{
transform.position = Vector3.MoveTowards(transform.position, target.transform.position, movespeed * Time.deltaTime);
} else //otherwise, we stop moving
{
movingtowardstarget = false;
}
}
}
I not got your movingtoward bool but you can handle your zoom easy.
First rotate your camera to look at your object and later apply zoom:
For example to zoom whith the mouse Wheel in a ortho camera you need to handle orthographicSize:
int orthographicSizeMin = 1;
int orthographicSizeMax = 6;
function Update()
{
transform.LookAt(target);
if (Input.GetAxis("Mouse ScrollWheel") > 0) // forward
{
Camera.main.orthographicSize++;
}
if (Input.GetAxis("Mouse ScrollWheel") < 0) // back
{
Camera.main.orthographicSize--;
}
}
Camera.main.orthographicSize = Mathf.Clamp(Camera.main.orthographicSize, orthographicSizeMin, orthographicSizeMax );
For a perspective camera you need to handle field of view:
float minFov = 10f;
float maxFov = 90f;
float sensitivity = 10f;
function Update()
{
transform.LookAt(target);
float fov = Camera.main.fieldOfView;
fov += Input.GetAxis("Mouse ScrollWheel") * sensitivity;
fov = Mathf.Clamp(fov, minFov, maxFov);
Camera.main.fieldOfView = fov;
}
Easiest way imo:
Add object for original position as well:
public GameObject targetobject, originalPosObj;
Then pass it as target:
movetowardstarget(movingtowardstarget ? targetObject : originalPosObj);
you can use the same function to zoom in and zoom out. please check the example below. Enter negative velocity to move backwards.
void Update()
{
if (Input.GetMouseButtonDown(1)) //move backward
movetowardstarget(targetobject, true);
if (Input.GetMouseButtonDown(0)) //move forward
movetowardstarget(targetobject, false);
}
public void movetowardstarget(GameObject target, bool backwards)
{
float dir = backwards?-1.0f:1.0f;
actualDist = Vector3.Distance(transform.position, target.transform.position);
if (Vector3.Distance(transform.position, target.transform.position) > minimumDistanceFromTarget) //we move only if we are further than the minimum distance
{
transform.position = Vector3.MoveTowards(transform.position, target.transform.position, dir*movespeed * Time.deltaTime);
}
else //otherwise, we stop moving
{
movingtowardstarget = false;
}
}
I imagine you will want to do this will the Mouse Wheel.
public class CameraConrol : MonoBehaviour
{
Vector3 centerPosition;//positon of object you want to zoom in and out of
float MaxZoom = 3f;
void Update()
{
//mouse wheel chaned
if (Input.mouseScrollDelta.y !=0)
{
ZoomCamera();
}
}
public void ZoomCamera()
{
Vector3 newPosition = Vector3.MoveTowards(
transform.position, centerPosition, Input.mouseScrollDelta.y);
if(newPosition.y >= (centerPosition.y + MaxZoom ))
{
transform.position = newPosition;
}
}
}
Hey I am making a top down game in unity. The problem I ma having is making npc players change the way they are facing while following the player. So if the player turns left the npc follows them but doesn't turn to face the direction the npc is going. I can get the npc to look like its walking just not change the direction it is looking. This is a 2d top down game please any help will be nice. here is my npc code.
using UnityEngine;
using System.Collections;
public class SlimeController : MonoBehaviour
{
public Transform Character; // Target Object to follow
public float speed = 0.1F; // Enemy speed
public float maxDist = 10.0f;
public float attackdistance = 3;
public float farenough;
private Vector3 directionOfCharacter;
private bool challenged = false;// If the enemy is Challenged to follow by the player
public Transform StartMarker;
private Vector3 goback;
public Transform EndMarker;
public Rigidbody2D rb;
Animator anim;
float oldx;
bool left;
bool right;
private void Start()
{
rb = GetComponent<Rigidbody2D>();
anim= GetComponent<Animator>();
oldx = transform.position.x;
}
void Update()
{
anim.SetBool("left", false);
anim.SetBool("right", false);
var distanceFromPlayer = Vector3.Distance(Character.position, transform.position);
if(oldx>transform.position.x)
{
left = false;
right = true;
}
if(oldx<transform.position.x)
{
left = true;
right = false;
}
if (oldx == transform.position.x)
{
left = false;
right = false;
}
if (challenged)
{
directionOfCharacter = Character.transform.position - transform.position;
directionOfCharacter = directionOfCharacter.normalized; // Get Direction to Move Towardsss
transform.Translate(directionOfCharacter * speed, Space.World);
enabled = true;
if (distanceFromPlayer < attackdistance)
{
attack();
}
if (distanceFromPlayer > attackdistance)
{
speed = 0.03f;
}
}
if (!challenged)
{
goback = StartMarker.transform.position - transform.position;
goback = goback.normalized;
transform.Translate(goback * speed, Space.World);
}
}
// Will be triggered as soon as player would touch the Enemy Object
void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.name == ("Player"))
{
challenged = true;
}
}
private void OnTriggerExit2D(Collider2D other)
{
if (other.gameObject.name == ("Player"))
{
speed = 0.03f;
challenged = false;
}
}
void attack()
{
speed = 0;
transform.Translate(directionOfCharacter * speed, Space.World);
}
}
This is because you are just moving the object towards your target. But to have it look at your target you need to also rotate it in the direction of your target.
The Transform Component has a function called LookAt. You supply it with your Target and the Axis your object should rotate around. So in your case:
this.transform.LookAt(Character, Vector3.up);
See here for more info on LookAt.