transform.Rotate an empty game object in unity - c#

I am trying to make an empty game object which is the path generator rotate when placing a tile left or right.
But somehow it does not rotate the object.
Plz help!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PathGenerator : MonoBehaviour
{
#region Settings
//Settings to customize this script
float gapSize = 0.4f; //0,4 coord gaps between squares
#endregion
public GameObject ChosenPath;
public GameObject NonChosenPath;
private Vector3 InitPos;
private Vector3 NextPos;
public Vector3 angleRotation;
public string pathDirection;
// Start is called before the first frame update
void Start()
{
InitPos = new Vector2(gapSize,gapSize);
NextPos = InitPos;
}
// Update is called once per frame
void Update()
{
if(Input.GetKey(KeyCode.Space))
{
ChangePath();
}
}
void ChangePath()
{
double randomNumQ = Random.Range(0,3);
if(randomNumQ == 0)
{
pathDirection = "Forward";
NextPos.y += gapSize;
}
else if(randomNumQ == 1)
{
pathDirection = "Left";
NextPos.x += gapSize;
angleRotation.z = -90;
transform.Rotate(angleRotation);
}
else if(randomNumQ == 2)
{
pathDirection = "Right";
NextPos.x -= gapSize;
angleRotation.z = 90;
transform.Rotate(angleRotation);
}
Instantiate(ChosenPath, NextPos, transform.rotation = Quaternion.identity);
transform.position = NextPos;
}
}

Actually the problem was that the Instantiate was after and it resets the rotation of the object

Related

How do I Instantiate a line renderer and give it positions for its points

I apologize for the block of code below but I am not sure where the issue is. I am trying to get a laser to appear off screen and attempt to hit the player. I have no idea why this code does nothing. It is most likey just a stupid mistake I have made.
`
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Lasers : MonoBehaviour
{
private LineRenderer lr;
public bool Above = true;
public bool Below = false;
public bool Left = false;
public bool Right = false;
public Transform LaserStartPoint;
public Transform LaserEndPoint;
public Transform Player;
public float LaserWidth = 0.75f;
public float LaserLength = 19f;
public float LaserDuration = 0.5f;
public float LaserFadeDuration = 0.5f;
public GameObject Laser;
void Update()
{
if(Input.GetKeyDown(KeyCode.Space))
{
ShootLaser();
}
}
void ShootLaser()
{
if(Above)
{
LaserStartPoint.position = new Vector3(Random.Range(-10,10), 6, -1);
}
if(Below)
{
LaserStartPoint.position = new Vector3(Random.Range(-10,10), -6, -1);
}
if(Left)
{
LaserStartPoint.position = new Vector3(-10, Random.Range(-6,6), -1);
}
if(Right)
{
LaserStartPoint.position = new Vector3(10, Random.Range(-6,6), -1);
}
Instantiate(Laser, LaserStartPoint.position, Quaternion.identity);
lr = Laser.GetComponent<LineRenderer>();
lr.startWidth = LaserWidth;
lr.endWidth = LaserWidth;
lr.positionCount = 2;
Vector3 dir = Player.position - LaserStartPoint.position;
LaserEndPoint.position = LaserStartPoint.position + dir.normalized * LaserLength;
lr.SetPosition(0, LaserStartPoint.position);
lr.SetPosition(1, LaserEndPoint.position);
Invoke("FadeLaser", LaserDuration);
}
void FadeLaser()
{
lr.startColor = Color.Lerp(lr.startColor, Color.clear, LaserFadeDuration);
lr.endColor = Color.Lerp(lr.endColor, Color.clear, LaserFadeDuration);
Laser.SetActive(false);
}
}
`
I have looked in the Hierarchy and nothing is spawning. None of the values are changing on the Script. I have the script attached to the main camera and it spawns in my LaserLineRenderer prefab.
You are attempting to modify the line renderer component of the prefab. You need to grab the reference of the instantiated object when it is spawned in.
private GameObject instantiatedLazer;
/*In ShootLaser function*/
instantiatedLazer = Instantiate(Laser, LaserStartPoint.position, Quaternion.identity);
lr = instantiatedLazer.GetComponent<LineRenderer>();
/*In FadeLaser function*/
instantiatedLazer.SetActive(false);

Is there a way to move object much faster on linerenderer line?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoveOnCurvedLine : MonoBehaviour
{
public LineRenderer lineRenderer;
public GameObject objectToMove;
public float speed;
public bool go = false;
public bool moveToFirstPositionOnStart = false;
private Vector3[] positions;
private Vector3[] pos;
private int index = 0;
// Start is called before the first frame update
void Start()
{
pos = GetLinePointsInWorldSpace();
if (moveToFirstPositionOnStart == true)
{
objectToMove.transform.position = pos[index];
}
}
Vector3[] GetLinePointsInWorldSpace()
{
positions = new Vector3[lineRenderer.positionCount];
//Get the positions which are shown in the inspector
lineRenderer.GetPositions(positions);
//the points returned are in world space
return positions;
}
// Update is called once per frame
void Update()
{
if (go == true)
{
Move();
}
}
void Move()
{
objectToMove.transform.position = Vector3.MoveTowards(objectToMove.transform.position,
pos[index],
speed * Time.deltaTime);
if (objectToMove.transform.position == pos[index])
{
index += 1;
}
if (index == pos.Length)
index = 0;
}
}
Even if I'm setting the speed value to 1000 or even to 10000 the speed is faster but not so fast or not very fast.
There are 1157 position in the variable array positions. So it's a bit a problem to move fast no so many positions and in other cases there might be 5000 positions or more depending on the linerenderer line length.
but I saw in some youtube demos cars and objects moving fast very fast on curved lines or very long length lines.
Figure out how much distance to move in the current frame, then loop through points until you've traveled that distance:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoveOnCurvedLine : MonoBehaviour
{
public LineRenderer lineRenderer;
public GameObject objectToMove;
public float speed;
public bool go = false;
public bool moveToFirstPositionOnStart = false;
private Vector3[] positions;
private Vector3[] pos;
private int index = 0;
// Start is called before the first frame update
void Start()
{
pos = GetLinePointsInWorldSpace();
if (moveToFirstPositionOnStart == true)
{
objectToMove.transform.position = pos[index];
}
}
Vector3[] GetLinePointsInWorldSpace()
{
positions = new Vector3[lineRenderer.positionCount];
//Get the positions which are shown in the inspector
lineRenderer.GetPositions(positions);
//the points returned are in world space
return positions;
}
// Update is called once per frame
void Update()
{
if (go == true)
{
Move();
}
}
void Move()
{
Vector3 newPos = objectToMove.transform.position;
float distanceToTravel = speed * Time.deltaTime;
bool stillTraveling = true;
while (stillTraveling)
{
Vector3 oldPos = newPos;
newPos = Vector3.MoveTowards(oldPos, pos[index], distanceToTravel);
distanceToTravel -= Vector3.Distance(newPos, oldPos);
if (newPos == pos[index]) // Vector3 comparison is approximate so this is ok
{
index = (index + 1) % pos.Length;
}
else
{
stillTraveling = false;
}
}
objectToMove.transform.position = newPos;
}
}

Unity 2D, control a simple shot

I have to control a shot of a ball with touch. All works fine but I need to start my trajectory when I touch the screen, but the trajectory start only when the ball is touched. Is because the script is attached to the ball?
All touch input except touches on the ball is ignored.
Here is the C# script , can someone help me?
using UnityEngine;
using System.Collections;
using System;
namespace Shorka.BallTrajectory
{
public enum PullState
{
Idle,
UserPulling,
ObjFlying
}
public class PullCtrl : MonoBehaviour
{
#region fields
//[SerializeField] private Transform throwTarget;
[SerializeField] private ThrownObject throwObj;
[SerializeField] private Transform dotHelper;
[SerializeField] private Transform pullingStartPoint;
[Space(5)]
[Tooltip("this linerenderer will draw the projected trajectory of the thrown object")]
[SerializeField]
private LineRenderer trajectoryLineRen;
[SerializeField]
private TrailMaker trail;
[Space(5)]
[SerializeField]
private float throwSpeed = 10F;
[Tooltip("Max Distance between 'PullingStartPoint' and pulling touch point")]
[SerializeField]
private float maxDistance = 1.5F;
[SerializeField]
private float coofDotHelper = 1.5F;
[Tooltip("Related to length of trajectory line")]
[SerializeField]
private int qtyOfsegments = 13;
[Tooltip("Step of changing trajectory dots offset in runtime")]
[SerializeField]
private float stepMatOffset = 0.01F;
[Tooltip("Z position of trajectory dots")]
[SerializeField]
private float dotPosZ = 0F;
private PullState pullState;
private Camera camMain;
//private Collider2D collThrowTarget;
private Rigidbody2D rgThrowTarget;
private Vector3 posPullingStart;
private Vector3 initPos;
private TrajectoryCtrl trajCtrl;
#endregion
public Vector3 PosDotHelper { get { return dotHelper.position; } }
public Vector3 PosThrowTarget { get { return throwObj.transform.position; } }
public int QtyOfsegments { get { return qtyOfsegments; } }
public float DotPosZ { get { return dotPosZ; } }
public Vector3 PosPullingStart { get { return posPullingStart; } }
public float StepMatOffset { get { return stepMatOffset; } }
void Awake()
{
trail.emit = false;
trajCtrl = new TrajectoryCtrl(this, trajectoryLineRen);
}
void Start()
{
camMain = Camera.main;
pullState = PullState.Idle;
posPullingStart = pullingStartPoint.position;
initPos = PosThrowTarget;
}
void Update()
{
SwitchStates();
}
private void SwitchStates()
{
switch (pullState)
{
case PullState.Idle:
if (Input.touchCount> 0 && Input.GetTouch(0).phase == TouchPhase.Began)
{
Debug.Log("Screen touched");
//get the point on screen user has tapped
Vector3 location = camMain.ScreenToWorldPoint(Input.GetTouch(0).position);
//if user has tapped onto the ball
if (throwObj.Collider == Physics2D.OverlapPoint(location))
pullState = PullState.UserPulling;
}
break;
case PullState.UserPulling:
dotHelper.gameObject.SetActive(true);
if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Moved)
{
//get touch position
Vector3 touchPos = camMain.ScreenToWorldPoint(Input.GetTouch(0).position);
touchPos.z = 0;
//we will let the user pull the ball up to a maximum distance
if (Vector3.Distance(touchPos, posPullingStart) > maxDistance)
{
Vector3 maxPosition = (touchPos - posPullingStart).normalized * maxDistance + posPullingStart;
maxPosition.z = dotHelper.position.z;
dotHelper.position = maxPosition;
}
else
{
touchPos.z = dotHelper.position.z;
dotHelper.position = touchPos;
}
float distance = Vector3.Distance(posPullingStart, dotHelper.position);
trajCtrl.DisplayTrajectory(distance);
}
else if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Canceled || Input.GetTouch(0).phase == TouchPhase.Ended)
{
float distance = Vector3.Distance(posPullingStart, dotHelper.position);
trajectoryLineRen.enabled = false;
ThrowObj(distance);
}
break;
default:
break;
}
}
//private Vector2 velocityToRg = Vector2.zero;
private void ThrowObj(float distance)
{
Debug.Log("ThrowObj");
pullState = PullState.Idle;
Vector3 velocity = posPullingStart - dotHelper.position;
//velocityToRg = CalcVelocity(velocity, distance);
throwObj.ThrowObj(CalcVelocity(velocity, distance));
//rgThrowTarget.velocity = velocityToRg;
//rgThrowTarget.isKinematic = false;
trail.enabled = true;
trail.emit = true;
dotHelper.gameObject.SetActive(false);
}
public void Restart(Vector3 posThrownObj)
{
trail.emit = false;
trail.Clear();
StartCoroutine(ClearTrail());
trajectoryLineRen.enabled = false;
dotHelper.gameObject.SetActive(false);
pullState = PullState.Idle;
throwObj.Reset(posThrownObj);
}
private readonly WaitForSeconds wtTimeBeforeClear = new WaitForSeconds(0.3F);
IEnumerator ClearTrail()
{
yield return wtTimeBeforeClear;
trail.Clear();
trail.enabled = false;
}
Vector3 velocity = Vector3.zero;
public Vector3 CalcVelocity(Vector3 diff, float distance)
{
velocity.x = diff.x * throwSpeed * distance * coofDotHelper;
velocity.y = diff.y * throwSpeed * distance * coofDotHelper;
return velocity;
}
}
}
Its quite easy. you need to add these two scripts to the gameobject (not the ball but the one which is used to shoot the ball something like a gun)
TouchEventTrigger.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
public class TouchEventTrigger : MonoBehaviour, IPointerClickHandler, IPointerDownHandler, IPointerUpHandler {
public TouchEvent onClick;
public TouchEvent onDown;
public TouchEvent onUp;
public void OnPointerClick(PointerEventData e) {
onClick.Invoke(e);
}
public void OnPointerDown(PointerEventData e) {
onDown.Invoke(e);
}
public void OnPointerUp(PointerEventData e) {
onUp.Invoke(e);
}
}
[System.Serializable]
public class TouchEvent : UnityEvent<PointerEventData> {}
Shooter.cs
public void TryBeginAim(PointerEventData e) {
if(canShoot) {
initialTouchPos = e.position;
}
}
public void TryAim(PointerEventData e) {
if(canShoot) {
direction = initialTouchPos - e.position;
float mag = (initialTouchPos - e.position).magnitude;
float scale = Mathf.Clamp(mag/maxMagnitude, scaleThreshold, 1f);
angle = Mathf.Atan2(direction.y,direction.x) * Mathf.Rad2Deg + 90f;
aim.transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);
aim.transform.localScale = Vector3.one * scale;
aim.SetActive(e.position.y < initialTouchPos.y);
}
}
public void TryShoot(PointerEventData e) {
if(canShoot && aim.activeInHierarchy) {
canShoot = false;
StartCoroutine(ShootRoutine(balls));
}
aim.SetActive(false);
}
private IEnumerator ShootRoutine(int b) {
// write code to start shooting balls.
}
Then connect the touch events with the methods like this:
1. OnPointerClick => TryBeginAim
2. OnPointerDown => TryAim
3. OnPointerUp => TryShoot
That's All !!
I hope this helps to solve this issue. Enjoy!

Switching camera to follow object in unity 3d

I'm trying to switch one camera to another to follow the sphere. What's happening in my script is, at first the main camera focuses the ball and as soon as it is grabbed and thrown, the main camera is switched off or disabled and the second camera is enabled to follow the ball when it is in motion. But the second camera doesn't follow in the direction of the ball. Below is the scripts that i implemented.
Note:- I'm attaching the second camera script at run time to second camera.
PickupObject.cs
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class pickupobject : MonoBehaviour
{
GameObject mainCamera;
//public GameObject empty;
bool carrying;
public GameObject carriedObject;
// Camera cam;
public float distances;
public float smooth;
float speed = 1000f;
private Vector3 offset;
public Camera camera;
private MovingBall script;
// Use this for initialization
void Start()
{
//cam = GameObject.Find("MainCamera").GetComponent<Camera>();
mainCamera = GameObject.FindWithTag("MainCamera");
camera = GameObject.FindWithTag("secondCamera").GetComponent<Camera>();
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.T) && carrying)
{
carrying = !carrying;
ThrowBall();
}
if (carrying)
{
carry(carriedObject);
// CheckDrop();
}
else
{
pickup();
}
}
private void pickup()
{
if (Input.GetKeyDown(KeyCode.E))
{
int x = Screen.width / 2;
int y = Screen.height / 2;
Ray ray = mainCamera.GetComponent<Camera>().ScreenPointToRay(new Vector3(x, y));
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
pickupable p = hit.collider.GetComponent<pickupable>();
if (p != null)
{
carrying = true;
carriedObject = p.gameObject;
camera.enabled = true;
camera.gameObject.AddComponent<CameraController>();
carriedObject.AddComponent<MovingBall>();
}
}
}
}
void carry(GameObject o)
{
o.GetComponent<Rigidbody>().isKinematic = true;
o.transform.position = mainCamera.transform.position + mainCamera.transform.forward * distances;
}
//void CheckDrop()
//{
// if (Input.GetKeyDown(KeyCode.U))
// {
// Drop();
// }
//}
//void Drop()
//{
// ThrowBall();
//}
void ThrowBall()
{
mainCamera.SetActive(false);
carriedObject.GetComponent<Rigidbody>().isKinematic = false;
carriedObject.GetComponent<Rigidbody>().AddForce(0f, 0f, speed);
}
}
CameraController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraController : MonoBehaviour {
// Use this for initialization
public GameObject icosphere;
private Vector3 offset;
pickupobject ball = new pickupobject();
void Start () {
ball.camera = GameObject.FindWithTag("secondCamera").GetComponent<Camera>();
//offset = transform.position - icosphere.transform.position;
//icosphere = GameObject.FindWithTag("yellowball");
// icosphere = ball.carriedObject.GetComponent<GameObject>();
offset = ball.camera.transform.position - GameObject.FindWithTag("purpleball").transform.position;
}
// Update is called once per frame
void LateUpdate () {
ball.camera.transform.position = GameObject.FindWithTag("purpleball").transform.position + offset;
// transform.position = ball.carriedObject.GetComponent<GameObject>().transform.position + offset;
}
}

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