Populating a list and Random select item in Unity - c#

I have a Unity script PlayerController.cs with game loginc and MyCity.cs in which a public class for MyCity is defined.
My goal is to populate the List in the PlayerController.cs.
The list contains cities and their x,y,z Vector3 coordinates.
My PlayerController script should randomly pick one city out of my list and use that in my SetTargetCity function so it can create a new gameobject with the appropriate Vector3 coordinates.
I am getting this error:
'The name mycities' does not exist in the current document'
What am I doing wrong? creating a public var for mycities doesn't do the trick....
MyCity.cs contains the following:
using UnityEngine;
using System.Collections;
public class MyCity
{
public string name;
public float xcor;
public float zcor;
public float ycor;
public MyCity(string newName, float newXcor, float newZcor, float newYcor)
{
name = newName;
xcor = newXcor;
zcor = newZcor;
ycor = newYcor;
}
}
Then the PlayerController script looks like this:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class PlayerController : MonoBehaviour
{
public float speed;
public float smooth = 2.0F;
public GUIText countText;
public GUIText targetCity;
private int count;
public GameObject cityPrefab;
void Start()
{
List<MyCity> mycities = new List<MyCity>();
mycities.Add( new MyCity("Maastricht", -5F, 3F, -1F ));
mycities.Add( new MyCity("Breda", -6F, 3F, -2F));
mycities.Add( new MyCity("Amsterdam", -2F, 3F, 4F));
//WHAT ELSE DO I NEED TO DO TO THE ABOVE LIST SO THAT
//THE BELOW FUNCTION void SetTargetCity () WILL WORK?
// scoring points & display on screen (works)
count = 0;
SetCountText ();
}
// Player Movement (works)
void FixedUpdate ()
{
float moveHorizontal = Input.GetAxis("Horizontal");
float moveVertical = Input.GetAxis("Vertical");
Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);
Vector3 moveDirection= new Vector3 (moveHorizontal, 0, moveVertical);
if (moveDirection != Vector3.zero){
Quaternion newRotation = Quaternion.LookRotation(moveDirection * -1);
transform.rotation = Quaternion.Slerp(transform.rotation, newRotation, Time.deltaTime * smooth);
rigidbody.AddForce(movement * speed * Time.deltaTime);
}
}
// Score points by flying into city game object (works), switch off that target city game object (works), get new target city...(no idea)
void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "City") {
other.gameObject.SetActive (false);
count = count + 1;
SetCountText ();
SetTargetCity ();
}
}
void SetCountText ()
{
countText.text = "Passengers Picked up: " + count.ToString();
}
// BELOW IS WHERE THINGS GO WRONG.
void SetTargetCity ()
{
var randomCity = mycities[0];
targetCity.text = "Fly to: " + randomCity.name.ToString();
GameObject instancedCity=(GameObject)GameObject.Instantiate(cityPrefab);
instancedCity.transform.position=new Vector3(randomCity.xcor,randomCity.ycor,randomCity.zcor);
}
}

Just define the myCities outside of your Start method and initialize it like this:
List<MyCity> mycities;
void Start()
{
mycities = new List<MyCity>();
...
}

Related

transform.Rotate an empty game object in unity

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

Why does the client sees himself falling through the ground?

Recently I tried making a multiplayer game and I have some problems. After I click "Play" in the menu and I get placed in the multiplayer scene, I see myself falling through the ground, and when I check the "Scene" tab in unity my character is standing where it should be and responds to my movements (as a player, all I can see is the infinite nothing around me but I can still look around, move, etc). When another player connects, he is bugged into the ground (and I can see the shadow from the other player that is hosting and plays directly from unity) and I can't move at all.
Code :
So in the main menu scene, I have this :
NetworkController script :
using Photon.Pun;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NetworkController : MonoBehaviourPunCallbacks
{
void Start()
{
PhotonNetwork.ConnectUsingSettings();
}
public override void OnConnectedToMaster () {
Debug.Log("coonnected to " + PhotonNetwork.CloudRegion + " server !");
}
void Update()
{
}
}
QuickStartLobbyController script:
using Photon.Pun;
using Photon.Realtime;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class StartLobbyController : MonoBehaviourPunCallbacks
{
[SerializeField] GameObject quickStartButton;
[SerializeField] float roomSize;
public override void OnConnectedToMaster () {
PhotonNetwork.AutomaticallySyncScene = true;
quickStartButton.SetActive(true);
}
public void QuickStart () {
quickStartButton.SetActive(false);
PhotonNetwork.JoinRandomRoom();
Debug.Log("Quick Start!");
}
public override void OnJoinRandomFailed (short returnCode, string message) {
Debug.Log("Failed to join a room");
CreateRoom();
}
public void CreateRoom () {
Debug.Log("creating room");
int randomRoomNumber = Random.Range(0, 10000);
RoomOptions roomOps = new RoomOptions() { IsVisible = true, IsOpen = true, MaxPlayers = (byte)
roomSize };
PhotonNetwork.CreateRoom("Room" + randomRoomNumber, roomOps);
Debug.Log(randomRoomNumber);
}
public override void OnCreateRoomFailed (short returnCode, string message) {
Debug.Log("failed to create a room");
CreateRoom();
}
}
QuickStartRoomController script :
using Photon.Pun;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RoomController : MonoBehaviourPunCallbacks
{
[SerializeField] int multiplayerSceneIndex;
public override void OnEnable () {
PhotonNetwork.AddCallbackTarget(this);
}
public override void OnDisable () {
PhotonNetwork.RemoveCallbackTarget(this);
}
public override void OnJoinedRoom () {
Debug.Log("joined room");
StartGame();
}
private void StartGame () {
if ( PhotonNetwork.IsMasterClient ) {
Debug.Log("Starting game");
PhotonNetwork.LoadLevel(multiplayerSceneIndex);
}
}
}
And now, the multiplayer scene where players should see each other:
The player has those :
The script inside GameSetup:
using Photon.Pun;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
public class GameSetupController : MonoBehaviour
{
void Start()
{
CreatePlayer();
}
private void CreatePlayer () {
Debug.Log("Creating Player");
PhotonNetwork.Instantiate(Path.Combine("PhotonPrefabs", "player"), Vector3.zero,
Quaternion.identity);
}
}
EDIT: so here you can see exactly how it looks like. When I play from the editor's window I can move around even if I can't see it, but with the client, I cannot do basically anything in-game. I think it might be a problem with the GameSetup code or with the part that syncs all the players with the server
EDIT2: posted the playerController script :
using Photon.Pun;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour, IPunObservable {
[SerializeField] Transform camera;
[SerializeField] float sens = 3.5f;
[SerializeField] float walkSpeed = 6.0f;
[SerializeField] [Range(0.0f, 0.5f)] float smooth = 0.3f;
[SerializeField] [Range(0.0f, 0.5f)] float smoothMouse = 0.3f;
[SerializeField] float gravity = -13.0f;
[SerializeField] float slopeForce = 6;
[SerializeField] float slopeForceRayLenght = 1.5f;
[SerializeField] float runSpeed = 10;
[SerializeField] float runBuildUp = 4;
[SerializeField] float jumpForce = 10;
[SerializeField] KeyCode jumpk;
[SerializeField] KeyCode runk;
[SerializeField] bool cursorLock = true;
public Rigidbody rb;
public Transform groundCheck;
public float groundDistance = 0.4f;
public LayerMask grndMask;
public bool isGrounded;
float cameraPitch = 0.0f;
float velocityY = 0.0f;
float speed;
Vector2 currentDir = Vector2.zero;
Vector2 currentDirVelocity = Vector2.zero;
Vector2 currentMouseDelta = Vector2.zero;
Vector2 currentMouseDeltaVelocity = Vector2.zero;
CharacterController controller;
PhotonView photonView;
private void Awake () {
photonView = GetComponent<PhotonView>();
photonView.ObservedComponents.Add(this);
if ( !photonView.IsMine ) {
enabled = false;
}
}
void Start () {
speed = walkSpeed;
controller = GetComponent<CharacterController>();
if ( cursorLock ) {
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
}
// Update is called once per frame
void Update () {
UpdateMouseLook();
UpdateMovement();
Jump();
}
void UpdateMouseLook () {
Vector2 mouseDelta = new Vector2(Input.GetAxis("Mouse
X"),Input.GetAxis("Mouse Y"));
currentMouseDelta = Vector2.SmoothDamp(currentMouseDelta, mouseDelta,ref
currentMouseDeltaVelocity, smoothMouse);
cameraPitch -= currentMouseDelta.y * sens;
cameraPitch = Mathf.Clamp(cameraPitch, -90.0f, 90.0f);
camera.localEulerAngles = Vector3.right * cameraPitch;
transform.Rotate(Vector3.up * currentMouseDelta.x * sens);
}
void SetSpeed () {
if ( Input.GetKey(runk) ) {
speed = Mathf.Lerp(speed, runSpeed, Time.deltaTime * runBuildUp);
} else {
speed = Mathf.Lerp(speed, walkSpeed, Time.deltaTime * runBuildUp);
}
}
void Jump () {
isGrounded = Physics.CheckSphere(groundCheck.position,
groundDistance,grndMask);
if ( isGrounded && Input.GetKeyDown(jumpk) ) {
Debug.Log("jumping");
velocityY = Mathf.Sqrt(jumpForce * -2f * gravity);
controller.Move(Vector3.up * velocityY * Time.deltaTime);
}
}
public bool OnSlope () {
RaycastHit hit;
if ( Physics.Raycast(transform.position, Vector3.down, out hit,
controller.height / 2 * slopeForceRayLenght) ) {
if ( hit.normal != Vector3.up ) {
return true;
}
}
return false;
}
void UpdateMovement () {
Vector2 inputDir = new Vector2(Input.GetAxisRaw("Horizontal"),
Input.GetAxisRaw("Vertical"));
inputDir.Normalize();
currentDir = Vector2.SmoothDamp(currentDir, inputDir, ref
currentDirVelocity, smooth);
if ( controller.isGrounded ) {
velocityY = 0.0f;
}
velocityY += gravity * Time.deltaTime;
Vector3 velocity = (transform.forward * currentDir.y + transform.right *
currentDir.x) * speed + Vector3.up * velocityY;
controller.Move(velocity * Time.deltaTime);
if ( (inputDir.x != 0 || inputDir.y != 0) && OnSlope() ) {
controller.Move(Vector3.down * controller.height / 2 * slopeForce *
Time.deltaTime);
}
SetSpeed();
}
void IPunObservable.OnPhotonSerializeView (PhotonStream stream,
PhotonMessageInfo info) {
if ( stream.IsWriting ) {
// We own this player: send the others our data
stream.SendNext(transform.position); //position of the character
stream.SendNext(transform.rotation); //rotation of the character
} else {
// Network player, receive data
Vector3 syncPosition = (Vector3) stream.ReceiveNext();
Quaternion syncRotation = (Quaternion) stream.ReceiveNext();
}
}
}
EDIT3: I found out something! When I enter the game from the master, I still need to drag myself up a bit in the editor and I will stop falling and I can play the game, but when the 2nd player connects, My camera is set to his (in all this time I can move my character and see this through the 2nd player's camera), and when he leaves all go back to normal on the master player. However, with the 2nd player, I can't move and I get an error that says:5. Btw the 2nd player is the session from the standalone (the built game) and the first player is a session from the unity editor

unity projectile spawns but doesn't pick up velocity?

This is my code does anyone know or can anyone spot why my projectile remains stationary once it's spawned in? the projectile is the prefab shell thanks for your help in advance.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TankBehaviour : MonoBehaviour
{
public GameObject shellPrefab;
public Transform fireTransform;
private bool isFired = false;
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
float x = Input.GetAxis("Horizontal");
float y = Input.GetAxis("Vertical");
transform.position += transform.forward * y;
transform.Rotate(0, x, 0);
if (Input.GetKeyUp(KeyCode.Space) && !isFired)
{
Debug.Log("fire!");
Fire();
}
}
void Fire()
{
//isFired = true;
GameObject shellInstance = Instantiate(shellPrefab,
fireTransform.position,
fireTransform.rotation) as GameObject;
if (shellInstance)
{
shellInstance.tag = "Shell";
Rigidbody shellRB = shellInstance.GetComponent<Rigidbody>();
shellRB.velocity = 15.0f * fireTransform.forward;
Debug.Log("velocity");
}
}
}
It is also generally discouraged to set the velocity of a rigidbody, but you can use the Rigidbody.AddForce() method to add force to a rigidbody. When you just want add force at the start, you can set the force mode in the function to impulse, like this rb.AddForce(Vector3.forward, ForceMode2D.Impulse);
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TankBehaviour : MonoBehaviour
{
public GameObject shellPrefab;
public Transform fireTransform;
private bool isFired = false;
public float bulletSpeed;
void Update()
{
float x = Input.GetAxis("Horizontal");
float y = Input.GetAxis("Vertical");
transform.position += transform.forward * y;
transform.Rotate(0, x, 0);
if (Input.GetKeyUp(KeyCode.Space) && !isFired)
{
Debug.Log("fire!");
Fire();
}
}
void Fire()
{
//isFired = true;
GameObject shellInstance = Instantiate(shellPrefab, fireTransform.position, fireTransform.rotation) as GameObject;
if (shellInstance)
{
shellInstance.tag = "Shell";
Rigidbody shellRB = shellInstance.GetComponent<Rigidbody>();
shellRB.AddForce(15f * transform.forward, ForceMode.Impulse);
Debug.Log("velocity");
}
}
}
Hope this helps!

How to make enemies turn and move towards player when near? Unity3D

I am trying to make my enemy object turn and start moving towards my player object when the player comes within a certain vicinity.
For the turning I have been testing the transform.LookAt() function although it isn't returning the desired results as when the player is too close to the enemy object the enemy starts to tilt backwards and I only want my enemy to be able to rotate along the y axis, thanks in advance.
using UnityEngine;
using System.Collections;
public class EnemyController : MonoBehaviour {
public Transform visionPoint;
private PlayerController player;
public Transform Player;
public float visionAngle = 30f;
public float visionDistance = 10f;
public float moveSpeed = 2f;
public float chaseDistance = 3f;
private Vector3? lastKnownPlayerPosition;
// Use this for initialization
void Start () {
player = GameObject.FindObjectOfType<PlayerController> ();
}
// Update is called once per frame
void Update () {
// Not giving the desired results
transform.LookAt(Player);
}
void FixedUpdate () {
}
void Look () {
Vector3 deltaToPlayer = player.transform.position - visionPoint.position;
Vector3 directionToPlayer = deltaToPlayer.normalized;
float dot = Vector3.Dot (transform.forward, directionToPlayer);
if (dot < 0) {
return;
}
float distanceToPlayer = directionToPlayer.magnitude;
if (distanceToPlayer > visionDistance)
{
return;
}
float angle = Vector3.Angle (transform.forward, directionToPlayer);
if(angle > visionAngle)
{
return;
}
RaycastHit hit;
if(Physics.Raycast(transform.position, directionToPlayer, out hit, visionDistance))
{
if (hit.collider.gameObject == player.gameObject)
{
lastKnownPlayerPosition = player.transform.position;
}
}
}
}
change the look at target:
void Update () {
Vector3 lookAt = Player.position;
lookAt.y = transform.position.y;
transform.LookAt(lookAt);
}
this way the look at target will be on the same height as your object.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class EnemyMovement : MonoBehaviour
{
public Transform Player;
public float MoveSpeed = 4;
int MaxDist = 10;
int MinDist = 5;
void Update()
{
transform.LookAt(Player);
if (Vector3.Distance(transform.position, Player.position) >= MinDist)
{
transform.position += transform.forward * MoveSpeed * Time.deltaTime;
if (Vector3.Distance(transform.position, Player.position) <= MaxDist)
{
// Put what do you want to happen here
}
}
}
}

Unity 2D Using Drag To Move Up And Down

I want to transform my game for Android and it's like pong. I want to be able to drag the paddle on a phone. Thanks ahead of time for the help. Here's my oldest code:
using UnityEngine;
using System.Collections;
public class MoveRacket : MonoBehaviour {
public float speed = 30;
public string axis = "Vertical";
void FixedUpdate () {
float v = Input.GetAxisRaw (axis);
GetComponent<Rigidbody2D> ().velocity = new Vector2 (0, v) * speed;
}
}
Heres my old code but it's still not working.
using UnityEngine;
using System.Collections;
public class MoveRacket : MonoBehaviour {
public float speed = 30;
public string axis = "Vertical";
public object racket = "Racket";
public bool touchInput = true;
public Vector2 touchPos;
void FixedUpdate () {
//used to not have anything in parentheses
float v = Input.GetAxisRaw (axis);
//GetComponent<Rigidbody2D> ().velocity = new Vector2 (0, v) * speed;
if (Input.touchCount == 1)
{
Vector3 wp = Camera.main.ScreenToWorldPoint(Input.GetTouch(0).position);
Vector2 touchPos = new Vector2(wp.x, wp.y);
if (racket == Physics2D.OverlapPoint(touchPos));
{
GetComponent<Rigidbody2D> ().velocity = new Vector2 (0, v) * speed;
}
}
}
}
Heres my current code that's now fixed.
using UnityEngine;
using System.Collections;
public class MoveRacket : MonoBehaviour {
public float speed = 30;
public string axis = "Vertical";
public object racket = "Racket";
public bool touchInput = true;
public Vector2 touchPos;
void FixedUpdate () {
//used to not have anything in parentheses
//float v = Input.GetAxisRaw (axis);
float v = Input.GetAxisRaw (axis);
GetComponent<Rigidbody2D> ().velocity = new Vector2 (0, v) * speed;
if (Input.touchCount == 1)
{
Vector3 wp = Camera.main.ScreenToWorldPoint(Input.GetTouch(0).position);
Vector2 touchPos = new Vector2(wp.x, wp.y);
if (Racket.Collider2D == Physics2D.OverlapPoint(touchPos));
{
this.transform.position.y = wp.y
}
}
}
}
Answer: Code above is fixed and should be usable.
You are saying you want to drag , Thus you will need touch
First you need to check for a touch that if the user is touching the screen then raycast2d to check if he is touching the paddle and use the same logic to keep it at the positon of finger that you used for mouse .
First try it Yourself , use this for hint
http://answers.unity3d.com/questions/577314/how-to-detect-if-a-sprite-was-object-was-touched-i.html
Thank you

Categories