Having a problem with loading scenes in unity3D EDITED CODE - c#

The player has a DontDestroyOnLoad function and I'm thinking that could be the issue because the player will delete copies of itself immediately
Alright, Heres the deal. When a player uses a door it SHOULD transport the player to another scene and then move them to the correct position and rotation. It does move to a new scene but it only occasionally moves the player to the correct position seemingly at random. How would I make this code more consistent? I'm at a loss with it.
Spawn Player Point is attached to an empty object in the world
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using StarterAssets;
public class StartPoint : MonoBehaviour
{
private ThirdPersonController thePlayer;
public string lastExitName;
private void OnSceneLoaded(Scene scene, LoadSceneMode mode) // use event rather than using the start method
{
thePlayer = FindObjectOfType<ThirdPersonController>();
if(thePlayer.nextSpawn == lastExitName)
{
thePlayer.transform.position = transform.position;
Debug.Log("moved to" + thePlayer.transform.position);
thePlayer.transform.eulerAngles = transform.eulerAngles;
Debug.Log("rotated to" + thePlayer.transform.eulerAngles);
}
}
private void Awake()
{
SceneManager.sceneLoaded += OnSceneLoaded;
}
private void OnDestroy()
{
SceneManager.sceneLoaded -= OnSceneLoaded;
}
/* public void WarpPlayer()
{
thePlayer = FindObjectOfType<ThirdPersonController>();
if(thePlayer.nextSpawn == lastExitName)
{
thePlayer.transform.position = transform.position;
Debug.Log("moved to" + thePlayer.transform.position);
thePlayer.transform.eulerAngles = transform.eulerAngles;
Debug.Log("rotated to" + thePlayer.transform.eulerAngles);
}
}
void Start()
{
thePlayer = FindObjectOfType<ThirdPersonController>();
if(thePlayer.nextSpawn == lastExitName)
Debug.Log(thePlayer.nextSpawn);
Debug.Log(lastExitName);
{
thePlayer.transform.position = transform.position;
Debug.Log("moved location to " + thePlayer.transform.position);
thePlayer.transform.eulerAngles = transform.eulerAngles;
Debug.Log("moved rotation to " + thePlayer.transform.eulerAngles);
}
}*/
private void OnDrawGizmosSelected()
{
Gizmos.color = Color.red;
Vector3 direction = transform.TransformDirection(Vector3.forward) * 5;
Gizmos.DrawRay(transform.position, direction);
}
}
This loads the new area
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using StarterAssets;
public class LoadNewLevel : MonoBehaviour
{
public string levelToLoad;
public string exitName;
private StartPoint startPoint;
private ThirdPersonController thePlayer;
void Awake()
{
startPoint = GameObject.FindGameObjectWithTag("SpawnPoint").GetComponent<StartPoint>();
thePlayer = FindObjectOfType<ThirdPersonController>();
}
public void MoveLevel()
{
thePlayer.nextSpawn = exitName;
Debug.Log("set Spawn to" + thePlayer.nextSpawn);
//PlayerPrefs.SetString("LastExitName", exitName);
SceneManager.LoadScene(levelToLoad);
Debug.Log("sceneloaded" + levelToLoad);
//startPoint.WarpPlayer();
}
}
the managing the players next spawn is managed in the player controller and is just a simple public string.

You can use the SceneManager.sceneLoaded event to ensure that the player is moved to the correct position after the new scene is fully loaded. The issue might be that things are happening before the scene is fully loaded?
private void OnSceneLoaded(Scene scene, LoadSceneMode mode) // use event rather than using the start method
{
thePlayer = FindObjectOfType<ThirdPersonController>();
if(thePlayer.nextSpawn == lastExitName)
{
thePlayer.transform.position = point.transform.position;
thePlayer.transform.eulerAngles = point.transform.eulerAngles;
}
}
private void Awake()
{
SceneManager.sceneLoaded += OnSceneLoaded;
}
private void OnDestroy()
{
SceneManager.sceneLoaded -= OnSceneLoaded;
}
Another thing I would suggest is to make use of Debug.Log()! It would be super helpful to place a Debug.Log() line after each chunk (if not each line) of code. This way you'll be able to make sure everything is being called correctly and in the right order.
It would be very interesting if you could Debug.Log() the player and the point position and rotation; It might be that the point position is off, who knows!

Related

Spawned Item Clone doesn't move like the original one

I'm making a 2D game and i have spawning potion items in a making potion scene first of all i want to make the item pop up after spown and go like in this video that i recorded from my game:
Spawned Item do not move like the original
what do i do to make the spawned (Cloned) Item move the same as the original potion item?
Secondly, i want to spawn random and more than one item (potion) each time the scene starts how do i do that knowing that i'm using this script that spawns only one object:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HerbSpawner : MonoBehaviour
{
//Here, we declare variables.
public GameObject objToSpawn;
public Transform groupTransform;
//public means the var is exposed in the inspector, which is super helpful.
// Start is called before the first frame update
Vector2 spawnPos;
void Start()
{
spawnPos = Camera.main.ViewportToWorldPoint(new Vector2(0.5f, 0.5f));
}
// Update is called once per frame
void Update()
{
//let's also spawn on button press:
if (Input.GetMouseButtonDown(0))
{
RaycastHit2D hit = Physics2D.GetRayIntersection(Camera.main.ScreenPointToRay(Input.mousePosition));
if (hit.collider && hit.collider.CompareTag("Bush"))
{
SpawnIt();
}
}
void SpawnIt()
{
Vector2 spawnPos = Camera.main.ViewportToWorldPoint(new Vector2(0.5f, 0.7f));
Instantiate(objToSpawn, spawnPos, Quaternion.identity, groupTransform);
}
}
}
please let me know if there is anyway to do it spawn multiple objects randomly and make the movement for the items to popup like in the video. This is teh script i used for that:
using System.Collections;
using UnityEngine;
using TMPro;
public class DragNDropItem : MonoBehaviour
{
public string itemName;
private bool dragging;
private Vector2 firstPos;
private Color spriteRenderer;
[SerializeField] private float speed = 3;
[SerializeField] private GameObject boiler;
public TMP_Text itemNameText;
private BoilerScript boilerScript;
public AudioSource drop;
void Awake()
{
// Initial position of the item
firstPos = transform.position;
boiler = GameObject.FindGameObjectWithTag("Boiler");
boilerScript = boiler.GetComponent<BoilerScript>();
spriteRenderer = gameObject.GetComponent<SpriteRenderer>().color;
}
void OnMouseDown()
{
dragging = true;
}
void OnMouseUp()
{
dragging = false;
if (Vector2.Distance(transform.position, boiler.transform.position) < 0.7f) // We control the distance between the item and the cauldron without using the collider.
{
itemNameText.text = itemName;
boilerScript.Potion(); // Checks the recipe's completion status each time an item is placed.
spriteRenderer.a = 0f;
gameObject.GetComponent<SpriteRenderer>().color = spriteRenderer;
StartCoroutine(Alpha());
}
else drop.Play(); // If the item is left
}
void Update()
{
if (dragging) // As soon as the item is clicked with the mouse, the item follows the mouse.
{
Vector2 mousePosition = MousePos();
transform.position = Vector2.Lerp(transform.position, mousePosition, speed * Time.deltaTime);
} else if (!dragging && (Vector2)transform.position != firstPos) // As soon as we stop clicking, it takes it back to its original place. While the item is in its original location, we are constantly preventing the code from running.
{
transform.position = Vector2.Lerp(transform.position, firstPos, speed * Time.deltaTime);
}
}
Vector2 MousePos() // position of mouse
{
return Camera.main.ScreenToWorldPoint(Input.mousePosition);
}
private IEnumerator Alpha() // After a second the item becomes visible.
{
spriteRenderer.a = 1f;
yield return new WaitForSeconds(0.6f);
gameObject.GetComponent<SpriteRenderer>().color = spriteRenderer;
}
}
Your colliders aren't set to trigger. My guess is, when a clone is spawned, it collides with the existing potion object.

Ball Breaker Game - Ball is getting stuck to paddle after certain bounces - Unity

I have created a block breaker game using Unity. Everything works fine except sometimes, the ball gets stuck to the paddle and then gets released after bit of time, causing it's speed to decrease. Please help as I am on the verge of completing my project :)
Here is the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Ball : MonoBehaviour
{
private Paddle paddle;
private Vector3 paddleToBallVector;
private bool hasStarted = false;
// Start is called before the first frame update
void Start()
{
paddle = GameObject.FindObjectOfType<Paddle>();
paddleToBallVector = this.transform.position - paddle.transform.position;
}
// Update is called once per frame
void Update()
{
if (!hasStarted)
{
//Lock the ball relative to paddle..
this.transform.position = paddle.transform.position + paddleToBallVector;
if (Input.GetMouseButtonDown(0))
{
print("Mouse Clicked, Ball Launched!!");
hasStarted = true;
this.GetComponent<Rigidbody2D>().velocity = new Vector2(2f, 10f);
}
}
}
void OnCollisionEnter2D(Collision2D c)
{
Vector2 tweak = new Vector2(Random.Range(0f,0.2f),Random.Range(0,0.2f));
if (hasStarted)
{
// GetComponent<AudioSource>().Play();
Rigidbody2D rigidbody = gameObject.GetComponent<Rigidbody2D>();
rigidbody.velocity += tweak;
}
}
}

Unity Jumping code for player not working

The jump button is not working in my unity, as my player is not jumping. I followed a tutorial but it does not seem to work. Must be something wrong with my code but I cannot seem to work it out as there are no errors.
I am not sure but, I created an image in unity and placed it in canvas and named it "Fixed Joybutton", with the script Joybutton.cs, but when I run it and try to click it, it wont make my player jump. I thought the problem was the "joybutton = FindObjectOfType();" and changed it to "joybutton = GetComponent();" but still doesnt work.
This is the code for the jump button itself, Joybutton.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
{
[HideInInspector]
public bool Pressed;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
public void OnPointerDown(PointerEventData eventData)
{
Pressed = true;
}
public void OnPointerUp(PointerEventData eventData)
{
Pressed = false;
}
}
// and this is the code that is in my player, PlayerController.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PlayerController : MonoBehaviour
{
protected Joystick joystick;
protected Joybutton joybutton;
protected bool jump;
public float speed;
public Text playerDisplay;
public Text scoreDisplay;
public bool isFlat = true;
private Rigidbody rb;
public static int count = 0;
private void Start()
{
joystick = FindObjectOfType<Joystick>();
joybutton = FindObjectOfType<Joybutton>();//this is to find the object, I changed it to "joybutton = GetComponent<Joybutton>();" but still doesnt work
rb = GetComponent<Rigidbody>();
}
private void FixedUpdate()
{
rb.velocity = new Vector3(joystick.Horizontal * 5f, rb.velocity.y, joystick.Vertical * 5f); // joystick to move my player, its working
if (!jump && joybutton.Pressed)// this is for the jump, that is not working
{
jump = true;
rb.velocity += Vector3.up * 10f;
}
if (jump && !joybutton.Pressed)
{
jump = false;
}
}
public void OnTriggerEnter(Collider other)
{
GameObject gameControl = GameObject.Find("Timer");//name of my gameobject
Loading loading = gameControl.GetComponent<Loading>();
if (other.gameObject.CompareTag("Pick Up"))
{
other.gameObject.SetActive(false);
count = count + 1;
Awake();
}
else if (other.gameObject.CompareTag("Time Boost"))
{
other.gameObject.SetActive(false);
loading.sec += 10;
if (loading.sec > 60)
{
int sec1 = loading.sec - 60;
loading.sec = sec1;
loading.minutes ++;
}
Awake();
}
}
private void Awake()
{
if (DBManager.username == null)
{
UnityEngine.SceneManagement.SceneManager.LoadScene(0);
}
playerDisplay.text = "Player: " + DBManager.username;//display username
scoreDisplay.text = "Score: " + count.ToString();//display score
}
}
//Player is moving but cannot jump. Please show me the error in my code and solution. Thank you so much.
There's a lot to unpack here.
UI Events like OnPointerDown occur on the frame cycle. FixedUpdate happens on the fixed cycle. There is a good chance that you have a very high framerate, resulting in 5-6 frames per fixed cycle. Your joybutton will only be set to "pressed" for one frame, so there is a very high chance that the joybutton triggers OnPointerUp before the jump can occur.
The quickest solution to this problem would be to not "reset" the joybutton's pressed state using OnPointerUp, and instead reset it when the jump is processed in your PlayerController. That being said, can you help me understand why these 2 scripts are separated?
Rather than set the .Pressed state to false in the JoyButton script, reset it after you consume it in your PlayerController:
if (!jump && joybutton.Pressed)// this is for the jump, that is not working
{
jump = true;
joybutton.Pressed = false; //Add this line of code
rb.velocity += Vector3.up * 10f;
}
How do yo do for avoiding the player to jump twice in the air?
private void FixedUpdate()
{
rb.velocity = new Vector3(
joystick.Horizontal * 5f, rb.velocity.y,
joystick.Vertical * 5f);
if (!jump && joybutton.Pressed)
{
jump = true;
rb.velocity += Vector3.up * 10f;
}
if (jump && !joybutton.Pressed)
{
jump = false;
}
}

Camera Follow for 2D - GameObjects Blink Out Upon Jump

Yes, I read through about 30 different similar titles before posting this. However, there wasn't anything relevant to what I need. I'm trying to set my camera's Y-axis to follow the player as it moves through the level; however, I don't want the camera to move up and down whilst jumping so I follow the camera's transform.position.y and NOT the player's.
void Pjump()
{
if (Input.GetKeyDown(KeyCode.Space) && onFloor==true
|| Input.GetKeyDown(KeyCode.W) && onFloor==true)
{
player.velocity = new Vector2(0, jump);
onFloor = false;
isJumping = true; // Static Variable to pass onto CamFollow script
}
}
isJumping is set false inside an OnCollisionEnter2d() and called inside of a FixedUpdate().
Now for the CamFollow script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CamFollow : MonoBehaviour
{
private GameObject p1;
private bool isFollow;
[Header("Camera Offset Values")]
[SerializeField]
private float xOff;
[SerializeField]
private float yOff;
void Start()
{
p1 = GameObject.FindWithTag("Player");
isFollow = true;
}
void FixedUpdate()
{
if (isFollow)
{
if (Pmove.isJumping == false) // This code works fine
{
transform.position = new Vector3(p1.transform.position.x + xOff, p1.transform.position.y + yOff,
transform.position.z);
}
if(Pmove.isJumping == true) // This is where the problem is: Y-Axis
{
transform.position = new Vector3(p1.transform.position.x + xOff, transform.position.y + yOff,
transform.position.z);
}
}
}
}
When the player jumps, the player and all non-UI objects vanish until the player touches the ground.

Mouse clicks aren't recognized when I build Unity game

EDIT : Apparently when I select Windowed, the buttons work. Why is this? Why doesn't it work without that box selected?
I created a game in Unity and everything works fine in Unity itself. When I build and run the game, my buttons no longer recognize my mouse clicks. Why is this?
This is a basic pong game. I don't know why it would work in Unity and not outside of Unity if it was the code but here is the code.
Code :
paddle script:
using UnityEngine;
using System.Collections;
public class paddle : MonoBehaviour {
public float paddleSpeed = 1;
public Vector3 playerPos = new Vector3(0,0,0);
// Update is called once per frame
void Update () {
float yPos = gameObject.transform.position.y + (Input.GetAxis ("Vertical") * paddleSpeed);
playerPos = new Vector3 (-20,Mathf.Clamp(yPos, -13F,13F),0);
gameObject.transform.position = playerPos;
}
}
ball script:
using UnityEngine;
using System.Collections;
public class Ball : MonoBehaviour {
public float ballVelocity = 1500;
private Rigidbody rb;
private bool isPlay; //false by default
int randInt; //random ball directon when game begins
// Use this for initialization
void Awake () {
rb = gameObject.GetComponent<Rigidbody> ();
randInt = Random.Range (1,3);
}
// Update is called once per frame
void Update () {
if(Input.GetMouseButton(0) == true && isPlay == false){
transform.parent = null;
isPlay = true;
rb.isKinematic = false;
if(randInt == 1){
rb.AddForce(new Vector3(ballVelocity,ballVelocity,0));
}
if(randInt == 2){
rb.AddForce(new Vector3(-ballVelocity,-ballVelocity,0));
}
}
}
}
enemy script:
using UnityEngine;
using System.Collections;
public class Enemy : MonoBehaviour {
public float speed = 8;
private Vector3 targetPos;
private Vector3 playerPos;
private GameObject ballObj;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
ballObj = GameObject.FindGameObjectWithTag ("ball");
if (ballObj != null) {
targetPos = Vector3.Lerp (gameObject.transform.position, ballObj.transform.position, Time.deltaTime * speed);
playerPos = new Vector3 (-20, Mathf.Clamp (targetPos.y, -13F, 13F), 0);
gameObject.transform.position = new Vector3 (20, playerPos.y, 0);
}
}
}
score script:
using UnityEngine;
using System.Collections;
public class Score : MonoBehaviour {
public TextMesh currScore;
public GameObject ballPref;
public Transform paddleObj;
GameObject ball;
private int score;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
ball = GameObject.FindGameObjectWithTag("ball");
currScore.text = "" + score;
}
void OnTriggerEnter(Collider other) {
if(other.tag == "ball"){
score += 1;
Destroy(ball);
(Instantiate(ballPref, new Vector3(paddleObj.transform.position.x + 1, paddleObj.transform.position.y,0), Quaternion.identity) as GameObject).transform.parent = paddleObj;
}
}
}
title screen script:
#pragma strict
function Start () {
}
function Update () {
}
function StartGame () {
Application.LoadLevel("Main");
}
function ExitGame () {
Application.Quit();
}
From what I am understanding, you want Unity to recognize your mouse button event even when the mouse pointer is not inside the game Window.
There could be 2 ways to achieve this:
1. The easy way, make your game full screen.
2. If you want your game in a window box, you must check "Run In Background" option in Player settings -> Resolution. And then, learn how to hook mouse event: http://www.codeproject.com/Articles/7294/Processing-Global-Mouse-and-Keyboard-Hooks-in-C
Please note that the hooking mouse event tutorial only works on Windows, not Mac nor Linux. I do not know how to do it with Mac or Linux.

Categories

Resources