I am trying to use Main Camera position to make an appear and disappear. For example, if the camera.main.transform.position = (0,2,0); make the object appear otherwise make it disappear.
The object in this case a basic Cube. I started using setActive function but as it turns out once you have setActive as false, Update function on the specific object does not run. I have added the script I was using:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class backandforth : MonoBehaviour
{
public float speed = 2.5f;
GameObject targetObject;
// Use this for initialization
void Start()
{
targetObject = GameObject.Find("Cube");
targetObject.SetActive(false);
}
// Update is called once per frame
void Update()
{
//move the cube from (0,0,0)
if (Camera.main.transform.position== new Vector3(0, 2, 0)) {
transform.position = new Vector3(Mathf.PingPong(Time.time * speed, 5), transform.position.y, transform.position.z);
transform.Rotate(0, 0, 5);
}
else
{
targetObject.SetActive(true);
transform.position = new Vector3(Mathf.PingPong(Time.time * speed, 5), transform.position.y, transform.position.z);
transform.Rotate(0, 0, 100);
//gameObject.SetActive(false);
}
}
}
Here is the hierarchy view of the setup to make the GameObject definition clear.
Any suggestion on how do I go about doing this? Thanks!
If I understand correctly the update method should be like this:
void Update()
{
if (Camera.main.transform.position== new Vector3(0, 2, 0)) {
//if the camera.main.transform.position = (0,2,0); make the object appear
targetObject.SetActive(true);
}
else
{
//otherwise make it disappear
targetObject.SetActive(false);
}
}
Related
I'm pretty new to Unity, and recently I've begun working on my first mobile game using C#, and suddenly I get the CS0117 error and I don't know why since my code is pretty simple and the console won't specify in which line the error occurs. I received the error when I wrote the simple line:
transform.position = new Vector3 (0, 0, 0);
in my player script to set it's position to the same as the position of the camera. I don't think that this has anything to do with the script itself, but that it is a problem with my phone, but I don't know what the problem is.
In case you need it, here are the full scripts of the player and the camera.
player script:
public class playerScript : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
transform.position = new Vector3 (0, 0, 0);
}
// Update is called once per frame
void Update()
{
//movement
if (Input.touchCount > 0)
{
Touch touch = Input.GetTouch(0);
Vector3 touchPosition = Camera.main.ScreenToWorldPoint(touch.position);
touchPosition.z = 0f;
transform.position = touchPosition;
}
//borders
if (transform.position.x >= 2.3f)
{
transform.position = new Vector3(2.3f ,transform.position.y, 0);
}
if (transform.position.x <= -2.3f)
{
transform.position = new Vector3(-2.3f ,transform.position.y, 0);
}
if (transform.position.y >= 4.5f)
{
transform.position = new Vector3(transform.position.x, 4.5f, 0);
}
if (transform.position.y <= -4.5f)
{
transform.position = new Vector3(transform.position.x, -4.5f, 0);
}
}
}
Camera script:
public class cameraScript : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
transform.position = new Vector3 (0, 0, 0);
}
// Update is called once per frame
void Update()
{
}
}
I am making my first foray into AI, specifically AI that will follow the player.
I am using the A* Path finding project scripts, but used the Brackeys tutorial for the code
https://www.youtube.com/watch?v=jvtFUfJ6CP8
Source in case needed.
Here's the code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Pathfinding;
public class EnemyAI : MonoBehaviour
{
public Transform Target;
public float speed = 200f;
public float NextWayPointDistance = 3f;
Path path;
int currentWaypoint = 0;
bool ReachedEndOfpath = false;
Seeker seeker;
Rigidbody2D rb;
public Transform EnemyGraphics;
// Start is called before the first frame update
void Start()
{
seeker = GetComponent<Seeker>();
rb = GetComponent<Rigidbody2D>();
InvokeRepeating("UpdatePath", 0f, 1f);
}
void UpdatePath()
{
if (seeker.IsDone())
seeker.StartPath(rb.position, Target.position, OnPathComplete);
}
void OnPathComplete(Path p)
{
if (!p.error)
{
path = p;
currentWaypoint = 0;
}
}
// Update is called once per frame
void fixedUpdate()
{
if(path == null)
return;
if(currentWaypoint >= path.vectorPath.Count)
{
ReachedEndOfpath = true;
return;
}
else
{
ReachedEndOfpath = false;
}
Vector2 Direction = ((Vector2)path.vectorPath[currentWaypoint] - rb.position).normalized;
Vector2 Force = Direction * speed * Time.fixedDeltaTime;
rb.AddForce(Force);
float distance = Vector2.Distance(rb.position, path.vectorPath[currentWaypoint]);
if(distance < NextWayPointDistance)
{
currentWaypoint++;
}
if(rb.velocity.x >= 0.01f)
{
EnemyGraphics.localScale = new Vector3(-1f, 1f, 1f);
}else if(rb.velocity.x <= 0.01f)
{
EnemyGraphics.localScale = new Vector3(1f, 1f, 1f);
}
}
}
How I tried to fix the issue:
I thought it could've been a problem with the speed so I increased it to 10000000, and still nothing
Next I thought it was a problem with the Rigidbody2d so I check there, found the gravity scale was set at 0, so I increased it to 1. It made my enemy fall to the ground but still no movement.
I thought it could've been a problem with the mass and drag, so I set Linear drag and Angular drag to 0, and also set mass to 1. Still nothing.
I set the body type to kinematic, pressed run, nothing. Set the body type to static, pressed run, nothing. Set the body type to Dynamic, pressed run, still nothing.
I tried to make a new target for the enemy to follow, dragged the empty game object i nto the target, pressed run and still didn't move.
I am at a loss on how to fix this.
Please help?
Looks like maybe a typo? You have:
// Update is called once per frame
void fixedUpdate()
{
but the method is called FixedUpdate(), with a big F in front. You have fixedUpdate, which is NOT the same.
On pressing the 'A' key i'm trying to spawn an asteroid within a set area away from the camera and also spawn a missile to take down this exact asteroid which spawns from under the camera. Ideally you should be able to press this key super fast and each time have a new asteroid and missile prefab spawn, which then are destroyed upon collision.
Issue: currently each missile goes towards the first object with the 'asteroid' tag assigned, rather than each missile firing at its respective asteroid. Also, when pressing super fast, some asteroids are missed completely and while the missiles are destroyed, these missed asteroids are not.
Here is my code, any help would be much appreciated!
Assigned to Missile prefab:
using System.Collections.Generic;
using UnityEngine;
public class launch : MonoBehaviour
{
// Use this for initialization
void Start()
{
}
// Update is called once per frame
public float speed;
void Update()
{
transform.position = Vector3.MoveTowards(transform.position, GameObject.FindGameObjectWithTag("Asteroid").transform.position, speed * Time.deltaTime);
}
void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.tag == "Asteroid")
{
Destroy(collision.gameObject);
Destroy(this.gameObject);
}
}
}
Assigned to blank game object where asteroids spawn
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SpawnAsteroid : MonoBehaviour
{
public GameObject Asteroidprefab;
public GameObject Missileprefab;
public Vector3 center;
public Vector3 ship;
public Vector3 size;
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.A))
{
SpawnSpaceRock();
}
}
public void SpawnSpaceRock()
{
Vector3 pos = center + new Vector3(Random.Range(-size.x / 2, size.x / 2), Random.Range(-size.y / 2, size.y / 2), Random.Range(-size.z / 2, size.z / 2));
Instantiate(Asteroidprefab, pos, Quaternion.identity);
Instantiate(Missileprefab, ship, Quaternion.identity);
}
private void OnDrawGizmosSelected()
{
Gizmos.color = new Color(1, 0, 0, 0.5f);
Gizmos.DrawCube(center, size);
}
}
It is very bad to use any Find method in Update since it is quite expensive!
it also returns only the first found GameObject.
What you want instead is store a target reference in launch when you initialize it and use that one
launch
public class launch : MonoBehaviour
{
public GameObject Target;
public float speed;
void Update()
{
transform.position = Vector3.MoveTowards(transform.position, Target.transform.position, speed * Time.deltaTime);
}
void OnCollisionEnter(Collision collision)
{
// Only collide with your specific target
if (collision.gameObject != Target) return;
Destroy(Target);
Destroy(this.gameObject);
}
}
SpawnAsteroide
// Hint of you use the correct component type here
// you don't even have to use GetComponent later
public launch MissilePrefab;
public GameObject Asteroideprefab;
//...
public void SpawnSpaceRock()
{
Vector3 pos = center + new Vector3(Random.Range(-size.x / 2, size.x / 2), Random.Range(-size.y / 2, size.y / 2), Random.Range(-size.z / 2, size.z / 2));
// store reference of Instantiated GameObject
var asteroide = Instantiate(Asteroidprefab, pos, Quaternion.identity);
// Store reference of Instantiated launch componemt
var missile = Instantiate(Missileprefab, ship, Quaternion.identity);
// Now set the taregt
missile.Target = asteroid;
}
Alternatively - single Update
sometimes the performance is better if you don't have a lot of objects running individual Update methods but having only one central Update method controlling them all. In this case you could e.g. use a dictionary
in SpawnAsteroide
public float speed;
private Dictionary<launch, GameObject> MissileToAsteroid = new Dictionary<launch, GameObject>();
public void SpawnSpaceRock()
{
Vector3 pos = center + new Vector3(Random.Range(-size.x / 2, size.x / 2), Random.Range(-size.y / 2, size.y / 2), Random.Range(-size.z / 2, size.z / 2));
// store reference of Instantiated GameObject
var asteroide = Instantiate(Asteroidprefab, pos, Quaternion.identity);
// Store reference of Instantiated launch componemt
var missile = Instantiate(Missileprefab, ship, Quaternion.identity);
// Since launch is still responsible for different both objects
// you still need to pass the reference
missile.Target = asteroid;
// Add to dictionary
MissileToAsteroid [missile] = asteroid;
}
And than run it all in your central Update method
void Update()
{
if (Input.GetKeyDown(KeyCode.A))
{
SpawnSpaceRock();
}
// TODO: Maybe later remove null elements for better performance
// Run each move towards
foreach(var kvp in MissileToAsteroid)
{
var missile = kvp.key;
var asteroid = kvp.value;
if(missile)
{
missile.transform.MoveTowards(missile.transform.possition, asteroid.transform.position, speed * Time.deltaTime);
}
}
}
and than let launch only handle the destroying of both objects (so remove the Update there)
In missle objects save target stone and use lists of missles and stones. Foreach missle in missle array move in Update
I'm new to Unity.
Below is my simple character controller C# script. I'm using 3d cubes with box colliders and rigid bodies as both my walls and player. Currently when my player comes into contact with a wall, it just keeps going.
Why is my script not working?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Controller : MonoBehaviour {
public float speed = 180;
private Rigidbody rig;
private Vector3 movement;
// Use this for initialization
void Start () {
rig = GetComponent<Rigidbody>();
}
// Update is called once per frame
void FixedUpdate () {
if (rig.velocity.magnitude <= 0)
{
if (Input.GetKeyUp("up"))
rig.velocity = new Vector3(0, 0, rig.position.z * speed );
else if (Input.GetKeyUp("down"))
rig.velocity = new Vector3(0, 0, rig.position.z * speed * -1);
else if (Input.GetKeyUp("right"))
rig.velocity = new Vector3(rig.position.x * speed, 0, 0);
else if (Input.GetKeyUp("left"))
rig.velocity = new Vector3(rig.position.x * speed * -1, 0, 0);
}
}
void OnCollisionEnter(Collision collision)
{
rig.velocity = Vector3.zero;
}
}
The script above works... My y position was higher than the position of my walls so there was never any collision. I feel dumb. Leaving post up as a reminder of my failure.
I have made a rocket in Unity that goes up and after 5 seconds lands. However, it lands like this:
I have to make it land upside down. How can I make this through code?
My current code as it is:
double t = 5.0;
void Update () {
GameObject Paraquedas;
GameObject CorpoNariz;
CorpoNariz = GameObject.Find("Corpo_Nariz");
Paraquedas = GameObject.Find("Paraquedas");
rigidbody.AddForce(transform.up * 15);
t -= Time.deltaTime;
if (t <= 0) {
Destroy (CorpoNariz);
Paraquedas.renderer.enabled = true;
transform.Rotate(Time.deltaTime, 0, 0);
rigidbody.AddForce(-transform.up * 50);
rigidbody.drag = 5;
}
}
}
Here's the script reference for transform.Rotate of Unity
http://docs.unity3d.com/Documentation/ScriptReference/Transform.Rotate.html
Try version 3 of Rotate functions. See the given example here:
void Rotate(Vector3 axis, float angle, Space relativeTo = Space.Self);
using UnityEngine;
using System.Collections;
public class Example : MonoBehaviour {
void Update() {
transform.Rotate(Vector3.right, Time.deltaTime);
transform.Rotate(Vector3.up, Time.deltaTime, Space.World);
}
}
Simply change the scale Y from 1 to -1 will do.
gameObject.transform.localScale = new Vector3(1,-1,1);