using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerControl : MonoBehaviour {
public GameObject player;
public GameObject arrow;
private Vector3 a;
private float angle;
private Rigidbody2D rb2D;
void Start()
{
}
void Update () {
if (Input.GetMouseButtonDown(0))
{
a = Input.mousePosition;
Vector2 difference = a - player.transform.position;
GameObject Aprefab = Instantiate(arrow) as GameObject;
rb2D = Aprefab.GetComponent<Rigidbody2D>();
rb2D.AddForce(difference * 0.02f, ForceMode2D.Impulse);
}
angle = Mathf.Atan2(rb2D.velocity.y, rb2D.velocity.x);
Aprefab.transform.localEulerAngles = new Vector3(0, 0, (angle * 180) / Mathf.PI);
}
}
Currently, I am making an arrow shooter.
I want to set arrow heading continuously while flying.
so I need to access "Aprefab" GameObject out of if block.
but how?
Need some help
To expand upon my comment: I've
refactored the shooting stuff into another function
added a list arrows to keep track of all the arrows fired (that Shoot() adds to)
made Update() iterate over all the arrows and update them
I don't have Unity at present, and this is dry-coded, so there might be some bugs.
Also, you'll want to take care of cleaning stuff up from the arrows list at some point.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerControl : MonoBehaviour {
public GameObject player;
private List<GameObject> arrows = new List<GameObject>();
void Start()
{
}
void Update () {
if (Input.GetMouseButtonDown(0))
{
Shoot();
}
foreach(var arrow in arrows) {
var rb2D = Aprefab.GetComponent<Rigidbody2D>();
var angle = Mathf.Atan2(rb2D.velocity.y, rb2D.velocity.x);
arrow.transform.localEulerAngles = new Vector3(0, 0, (angle * 180) / Mathf.PI);
}
}
private void Shoot() {
var a = Input.mousePosition;
var difference = a - player.transform.position;
var Aprefab = Instantiate(arrow) as GameObject;
var rb2D = Aprefab.GetComponent<Rigidbody2D>();
rb2D.AddForce(difference * 0.02f, ForceMode2D.Impulse);
arrows.Add(Aprefab);
}
}
Related
I want to move an object from position A to position B on X axis endlessly. But it does move and comeback only once. How to make it continuosly? I've tried Vector3.Lerp or just creating new Vector3 but it only teleports.
`
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MovingTarget : MonoBehaviour
{
[SerializeField] private Vector3 firstPosition = new Vector3(-14f, 2.5f, 17f);
[SerializeField] private Vector3 secondPosition = new Vector3(14f, 2.5f, 17f);
public float speed = 10f;
void Start()
{
transform.position = firstPosition;
}
void Update()
{
transform.position = Vector3.MoveTowards(transform.position, secondPosition, Time.deltaTime * speed);
if(transform.position == secondPosition)
{
secondPosition = firstPosition;
}
}
}
`
As alternative you could also use Mathf.PingPong like e.g.
// By default afaik a full cycle takes 2 seconds so in order to normalize
// this to one second we will divide by this times 2 later
public float cycleDuration = 1;
private void Update ()
{
transform.position = Vector3.Lerp(firstPosition, secondPosition, Mathf.PingPong(Time.time / (cycleDuration * 2f), 1f));
}
In case your object is spawned later in the game you might want to rather always start at the first position and do
private float timer;
private void Update ()
{
transform.position = Vector3.Lerp(firstPosition, secondPosition, Mathf.PingPong(timer / (cycleDuration * 2f), 1f));
timer += Time.deltaTime;
}
I don't use Unity, but since nobody else answered....
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MovingTarget : MonoBehaviour
{
[SerializeField] private Vector3 firstPosition = new Vector3(-14f, 2.5f, 17f);
[SerializeField] private Vector3 secondPosition = new Vector3(14f, 2.5f, 17f);
private Vector3 target;
public float speed = 10f;
void Start()
{
transform.position = firstPosition;
target = secondPosition;
}
void Update()
{
transform.position = Vector3.MoveTowards(transform.position, target, Time.deltaTime * speed);
if (transform.position == firstPosition)
{
target = secondPosition;
}
else if (transform.position == secondPosition)
{
target = firstPosition;
}
}
}
Should I use Cinemachine for that or it's better to do it with a script from scratch ?
The script is attached to the Main Camera.
Now it's orbit only left right. I want it to orbit 360 degrees with clamp so it wont move down to the floor and to up back.
I should also the Y and not only the X but not sure how.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerFollow : MonoBehaviour {
public Transform PlayerTransform;
private Vector3 _cameraOffset;
[Range(0.01f, 1.0f)]
public float SmoothFactor = 0.5f;
public bool LookAtPlayer = false;
public bool RotateAroundPlayer = true;
public float RotationsSpeed = 5.0f;
// Use this for initialization
void Start () {
_cameraOffset = transform.position - PlayerTransform.position;
}
// LateUpdate is called after Update methods
void LateUpdate () {
if(RotateAroundPlayer)
{
Quaternion camTurnAngle =
Quaternion.AngleAxis(Input.GetAxis("Mouse X") * RotationsSpeed, Vector3.up);
_cameraOffset = camTurnAngle * _cameraOffset;
}
Vector3 newPos = PlayerTransform.position + _cameraOffset;
transform.position = Vector3.Slerp(transform.position, newPos, SmoothFactor);
if (LookAtPlayer || RotateAroundPlayer)
transform.LookAt(PlayerTransform);
}
}
I tried to make a firefly for my game, which is an AI.I wanted it to make across the map, for that I watched a tutorial on YT from BlackThornProd, but when I tried animating it, and played the game, it was terrible, the animation were playing bizarre, like when the firefly needs to go on the right, the animations are playing like this; Left-Right-Idle-Right-etc.Im using Blend Tree.
How can I solve it?
Thanks
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NPCRandomMoveing : MonoBehaviour
{
public float speed;
public Transform[] moveSpots;
private int randomSpot;
private float waitTime;
public float startWaitTime;
public Animator anim;
Vector2 movement;
void Start()
{
waitTime = startWaitTime;
randomSpot = Random.Range(0, moveSpots.Length);
}
void Update()
{
transform.position = Vector2.MoveTowards(transform.position, moveSpots[randomSpot].position, speed * Time.deltaTime);
if(Vector2.Distance(transform.position, moveSpots[randomSpot].position) < 0.2f){
if(waitTime <= 0){
randomSpot = Random.Range(0, moveSpots.Length);
waitTime = startWaitTime;
} else {
waitTime -= Time.deltaTime;
}
}
}
void FixedUpdate(){
anim.SetFloat("Horizontal", transform.position.x);
anim.SetFloat("Vertical", transform.position.y);
anim.SetFloat("Speed", transform.position.sqrMagnitude);
}
}
I think you move your fly and also try to animate its position right? Try maybe to just animate and dont change the transforms or even better rotate your fly with lookat vector and use animation controler to just adjust the speed of wings.
Try this script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RotateTowardsSpline : MonoBehaviour
{
// put the points from unity interface
public List<Transform> wayPointList = new List<Transform>();
public int currentWayPoint = 0;
Transform targetWayPoint;
public float speed = 0f;
public float turningRate = 1f;
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void FixedUpdate()
{
if (currentWayPoint < this.wayPointList.Count - 1)
{
if (targetWayPoint == null)
targetWayPoint = wayPointList[currentWayPoint];// hier put a random nr
RotateTowards();
}
}
void RotateTowards()
{
// rotate towards the target
transform.forward = Vector3.RotateTowards(transform.right, targetWayPoint.position - transform.position, 0.02f * (speed) * Time.deltaTime, 1.0f);
}
}
So i made a little side scroller that uses a prefab to spawn bullets.
My problem is that it only shoots to one side... the Right.
I need it to fire to the left as well. I've already made a variable to see if the player is looking to the right or left.
I've tried to put the Speed to -20 and i've tried to rotate it 180 degrees on it's Z axis. I tested if the bullet script even picked up the change from the player movement script and it does.
Player Movement script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public GameObject bullet;
private Rigidbody2D myRigidbody;
private float speed = 15;
private bool facingRight;
private bool ground = false;
private float jump = 23;
// Start is called before the first frame update
void Start()
{
facingRight = true;
myRigidbody = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void FixedUpdate()
{
float horizontal = Input.GetAxis("Horizontal");
Movement(horizontal);
Flip(horizontal);
if (Input.GetKey("w"))
{
if (ground)
{
GetComponent<Rigidbody2D>().velocity = new Vector2(GetComponent<Rigidbody2D>().velocity.x, jump);
}
}
if(facingRight == false)
{
bullet.GetComponent<bullet>().left = true;
}
if (facingRight == true)
{
bullet.GetComponent<bullet>().left = false;
}
}
void OnTriggerEnter2D()
{
ground = true;
}
void OnTriggerExit2D()
{
ground = false;
}
private void Movement(float horizontal)
{
myRigidbody.velocity = new Vector2(horizontal * speed,myRigidbody.velocity.y);
}
private void Flip(float horizontal)
{
if (horizontal > 0 && !facingRight || horizontal < 0 && facingRight)
{
facingRight = !facingRight;
Vector3 theScale = transform.localScale;
theScale.x *= -1;
transform.localScale = theScale;
}
}
}
Weapon script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class weapon : MonoBehaviour
{
// Start is called before the first frame update
public bool right;
public Transform firepointR;
public GameObject bulletPrefab;
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown("space"))
{
Debug.Log("Oh well");
Shoot();
}
}
void Shoot()
{
Instantiate(bulletPrefab, firepointR.position, firepointR.rotation);
}
}
bullet script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class bullet : MonoBehaviour
{
public bool left;
public float speed = 20;
public Rigidbody2D rb;
// Start is called before the first frame update
void Start()
{
rb.velocity = transform.right * speed;
}
// Update is called once per frame
void FixedUpdate()
{
Debug.Log(speed);
if (left == false)
{
transform.Rotate(0, 0, 180);
}
}
}
As i previously said i need my bullet (prefab) to go the opposite direction but whatever i do right now it will always go right.
Expanding on my comment:
Did you try reversing the velocity?
rb.velocity = -(transform.right * speed);
Note: There are instances when using a negative float wont return the opposite of the positive result. However, in this example, it will work just fine.
I imagine this will work also (and is probably the correct way of doing it):
rb.velocity = transform.left * speed;
I'm creating a 2D horizontal side-scroller and I have enemies being spawned whose rigidbody component is being used to give them a velocity like so:
using UnityEngine;
using System.Collections;
public class Mover : MonoBehaviour
{
public float speed;
public new Rigidbody2D rigidbody;
public bool random;
void Start()
{
if (random) {
rigidbody.velocity = Random.value * transform.right * speed;
}
else
{
rigidbody.velocity = transform.right * speed;
}
}
}
How can I have these enemies also move up and down constantly on the the Y-axis while they are moving with a velocity on the X-axis? Everything I have tried seems to interfere with the velocity of the objects. I am basically trying to create a simple behavioral pattern so as to make the targets harder for the player to aim at.
Any ideas?
This is just a starting point, but you would have to experiment with different ways to do it to get the behavior you want. Maybe you can try using rigidbody.AddForce too.
If you haven't already, I recommend watching the video tutorials for the 2D platformer.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(Rigidbody2D))]
public class Mover : MonoBehaviour {
public float speed, waveSpeed;
new Rigidbody2D rigidbody;
public bool random;
// Use this for initialization
void Start () {
rigidbody = GetComponent<Rigidbody2D>();
if (random) {
rigidbody.velocity = Random.value * transform.right * speed;
} else {
rigidbody.velocity = transform.right * speed;
}
}
float angle = 0;
// Use this for physics calculations
void FixedUpdate () {
var wave = Mathf.Sin(angle += waveSpeed); // goes from -1 to +1
var p = rigidbody.position;
p.y = wave; // or: yCenter + yHeight * wave
rigidbody.position = p;
}
}
I have found the solution by following the answer given under this link: https://gamedev.stackexchange.com/questions/96878/how-to-animate-objects-with-bobbing-up-and-down-motion-in-unity?newreg=ccb2eaf1b725413ca777a68348637990
Here is my updated code:
public class EnemyMover : MonoBehaviour {
public float speed;
public new Rigidbody2D rigidbody;
public bool random;
float originalY;
public float floatStrength = 1;
void Start()
{
this.originalY = this.transform.position.y;
if (random) {
rigidbody.velocity = Random.value * transform.right * speed;
}else
{
rigidbody.velocity = transform.right * speed;
}
}
void Update()
{
transform.position = new Vector3(transform.position.x,
originalY + ((float)System.Math.Sin(Time.time) * floatStrength),
transform.position.z);
}
}