My Fist Game! Please Help Me!

Hi

I startet to learn unity for 1 year ago and still not managed to put together a full mobile game. I start my development many times and get stuck, i get depressed and i quit. So now i am going to try for the last time. I am going to post all my game development process here in this post. Please give feedback to my development process

What i am going to make this time is for only learning process. So iam going to copy game like The line Zen

What i have done so far
-Player Script
-MoveingPlatform

My first question;
Should i make the ball move forward or make platform(level) move as i have done it now?

If ball is moving forward:
How can i spawn random levels easily(Object Pooling)?
How will this affect gameplay?.
Can use DontGoThroughThings.cs if ball is moving forward.

If Platform(level) moving backward
How can i spawn random levels easily(Object Pooling)?
How will this affect gameplay?.
I cant use DontGoThroughThings.cs if ball is not moving forward.

Player Script: Ball can only be moved left and right.

using UnityEngine;
using System.Collections;

public class Player : MonoBehaviour {

    [SerializeField] private float ballSpeed = 800;

    private Rigidbody myRB;

    void Awake(){
        myRB = GetComponent<Rigidbody> ();
    }

    void FixedUpdate(){
        float moveH = Input.GetAxis ("Horizontal");
        Vector3 movement = new Vector3 (moveH, 0f, 0f);
        myRB.velocity = (movement*ballSpeed*Time.deltaTime);
    }
}

Anything i should do differently in Player script?

Moving Platform: This is attached to every level.

using UnityEngine;
using System.Collections;

public class MovingObject : MonoBehaviour {

    public float speed = 200;

    void Update () {
        Move ();
    }

    void Move(){
        Vector3 movement =  Vector3.back * (speed / 10) * Time.deltaTime;
        transform.Translate (movement, Space.World);
    }
}

2976335--221229--LevelLoad.jpg

@Samantha_K I’m very new to Unity and this may or may not be correct, but I noticed in the Player script and the Moving Platform script your floats do not have the letter f after the value you give it.

Another thing you might try is the Rolling Ball tutorial on Unity. That may solve the problem of the ball not moving forward.

Good luck with your project. I hope either of those help you solve part of your problem.

1 Like

Thank you for your reply. Iam very very slow learner. :frowning:

It’s perfectly acceptable to leave off the float designator on whole numbers.

public float speed = 200; - Does not cause an error

public float speed = 200.0; - Does cause an error

@Samantha_K there are tutorials on instantiating and object pooling on the interwebs. This subject is too big and too complicated to provide a quick answer and this something that you must learn on your own. As for your scripts, do you have any specific problems? There are more ways to do something and usually no right way. If your scripts are working properly, leave them alone and focus on you next real problem.

1 Like

Hi @Bill_Martini Thank you for your reply. I understand that Object pooling is complicated and i have to learn that on my own. What iam actually asking is what is right method to use? Object pooling or any other way?

A level is empty gameObject (ex: Level01) with child gameobjects. Child Gameobjects are pre designed pattern. Each levels has diffrent patterns. Patterns are made with moving and rotating objects, some objects (Green boxes) has Rigidbody attached.

What iam going to try now is create ObjectPooling scripts and attache that to parent GameObject (Level01,leve02…). Thank you for your time @ and @DocJ

1 Like

See? I told you I was new. Lol. Now I learned something new too.

@Samantha_K , you are putting the cart way ahead of the horse. Object pooling is something you worry about when your game is pretty much done and you have profiled it and found that object creation is a bottleneck.

You haven’t done any of that yet, so you should not be worrying about object pooling.

Instead, you should be focused on making things appear on the screen and move around the way you want them to. And you should do this in the simplest way possible. At every turn, ask yourself “how many ways can I think of to do this?” Then…

  • If the answer is zero, do some more tutorials, or ask for help.
  • If the answer is one, then ask yourself “but could there be an easier way?” If not sure, do some more tutorials, or ask for help.
  • If the answer is “lots,” then look at each one and see which is the simplest way. Do it that way.

Usually there is a quite simple way to do things in Unity, so if something looks really complicated, it’s possible you are missing a simpler approach.

Remember, the greatest risk to your project is that you will never finish it. So don’t be ashamed to cut corners, simplify your design, and always do the bare minimum! Your goal is to get to the end of the project. And I know you can do it!

7 Likes

@JoeStrout THANK YOU SO MUCH!. Now i understand why i am failing all the time. I think too much and make it too complicated for me and i get depressed. This apply not only for my gamedev, I think too much about anything. I greatly appreciate your kind words. @JoeStrout . Thank you again. Iam going to try to do simple tings first.

1 Like

I try to think of it like writing a novel. The key is to get the 50,000+ words on paper. They don’t have to be the best words, or even really good words, but you have to have that story written out before you can go back and polish it. You can’t polish what doesn’t exist in other words. So when writing you must turn off your internal editor and just write the words.

Finishing your game is similar. Don’t worry too much about art or music or polish. Just get things on the screen, get them moving, make the game flow the way you want it to. Once you have it done, then you can go back and spend all of the time you want to making it pretty.

2 Likes

Hi, Thank you @Dave-Carlile .

Now i started to work on my movingObstacles. To answer my own question

I found out that i should make ball(player) move forward so that ball can hit object with rigidbody attached to.

I have been working on movingObstacles today and here is what i have done so far:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MovingObstacle : MonoBehaviour {
 
    [Header("Rotate Object")]
    [SerializeField] private Vector3 rotateXYZ;
    [SerializeField] private bool randomRotateSpeed;
    [SerializeField] private Vector2 randomRotateSpeedMinMax;
    [Range(0, 5)]
    [SerializeField] private float rotatingSpeed;

    [Header("Move Object")]
    [SerializeField] private bool canMove;
    [SerializeField] private Vector3 moveLength;
    [SerializeField] private bool randomMoveSpeed;
    [SerializeField] private Vector2 randomMoveSpeedMinMax;
    [Range(0, 3)]
    [SerializeField] private float speed = 1;
    private Vector3 startPosMovingObj;
    private Vector3 movementLength;

    [Header("PopUp Object")]
    [SerializeField] private bool canPopUp;
    [SerializeField] private bool randomPopUpSpeed;
    [SerializeField] private Vector2 randomPopUpSpeedMinMax;
    [Range(0, 4)]
    [SerializeField] private float popUpSpeed;
    [SerializeField] private Vector3 popUpLength;
    [SerializeField] private float wakeUpInn;
    private Vector3 startPosPopUpObj;

    void Start(){
        StartPosition ();
        RandomSpeed ();

    }

    // Update is called once per frame
    void Update () {
        Rotate ();
        PingPong ();
        PopUp ();
    }

    void Rotate(){
        transform.Rotate(rotateXYZ*rotatingSpeed*Time.deltaTime);
    }

    void PingPong(){
        if (canMove == true) {
            float pingPong = Mathf.PingPong(Time.time * speed, 1);
            transform.position = Vector3.Lerp(startPosMovingObj, movementLength, pingPong);
        }
    }

    void PopUp(){
        if (canPopUp==true) {
            float step = popUpSpeed * Time.deltaTime;
            transform.position = Vector3.MoveTowards (transform.position, startPosPopUpObj, step);
        }
    }

    void StartPosition(){
        //Get start position of Pop up object.
        startPosPopUpObj = new Vector3 (transform.position.x + popUpLength.x, transform.position.y + popUpLength.y, transform.position.z + popUpLength.z);
        //Get start position of moving object.
        startPosMovingObj = this.transform.position;
        Vector3 temp = moveLength;
        movementLength =  new Vector3 (transform.position.x + temp.x, transform.position.y + temp.y, transform.position.z + temp.z);
    }

    void RandomSpeed(){
        if (randomPopUpSpeed == true) {
            float randomSpeed = Random.Range (randomPopUpSpeedMinMax.x, randomPopUpSpeedMinMax.y);
            popUpSpeed = randomSpeed;
        }
        if (randomMoveSpeed == true) {
            float randomSpeed = Random.Range (randomMoveSpeedMinMax.x, randomMoveSpeedMinMax.y);
            speed = randomSpeed;
        }
        if (randomRotateSpeed == true) {
            float randomSpeed = Random.Range (randomRotateSpeedMinMax.x, randomRotateSpeedMinMax.y);
            rotatingSpeed = randomSpeed;
        }
    }
}

i know that code is not very clean… :(. but iam still working on it. This script is working nice so far :slight_smile: .Iam planning on attaching this script to many objects(over 100 objects in one level).

What iam having trouble now is:
How can i make “PopUp” Object pop up when player get closer. If diffrence between player and object is less then 5, object moves up. How can i do that?

I found this, but in this script i have to use player = GameObject.FindGameObjectWithTag("Player").transform;

If over 100 of object have my “MovingObstacle” scripts and all is trying to “FindGameObjectWithTag” wont this slow down performance. Iam developing game for mobile platform.

am i thinking too much agian? :confused:

well, maybe.
please don’t get me wrong, it’s good to think about such things that will affect your players, the best thing you can do to know if something will crash your game in mobile is to try it in your own device. That’s the best thing you can do to test if some part code can or can’t slow down your game’s performance, try to print on screen the fps rate before this code and make whatever you want and print again while runing this code and see if it works or not :slight_smile:

1 Like

@sheepixel Thank you for your reply. I will try that :slight_smile:

Edit;
framerate is dropping when using player = GameObject.FindGameObjectWithTag("Player").transform;
so i have to find another way.

Thank you again @sheepixel for advice.

it is a guess, but maybe you could make it public and drag and drop the player object to the enemy inspector in your code, but i think it is basicaly the same thing you do in code, but i am not sure. It is worth it a try.

You’ll be fine if you only call FindGameObjectWithTag in the Start method, storing the result in a field on the script. It’s only a problem if you call it every frame.

Your code looks very good, by the way. I like how you have it divided into several small, simple methods rather than one big ugly method!

I have just a couple of small style suggestions…

  • Using “[SerializeField] private” on every field seems like working harder than you need to. I understand the arguments for it, but it’s really not likely to be a problem if you simply declare any field as “public” if you want it to appear in the Inspector, and as nothing (implicitly private) otherwise. Yes, this means that some other script could in theory access those properties — but it’d have to get a reference to it first, which is hard enough that you’re not too likely to do it thoughtlessly. So I say, keep the code simple unless you find it’s actually a problem.
  • When checking boolean flags, you don’t need to say “if (something == true)”. Just say “if (something)” instead. It means the same thing, and is shorter (and I think clearer, but I guess opinions may vary on that).

Of course you can develop your own style! These are just some ideas to maybe make writing the code easier.

Any Find method to get references to gameobjects should be called as sparingly as possible, since they have to iterate through the complete scene which is quite computation heavy for any non-trivial scene.

If you want an object to react to the proximity to another object, the easiest method would be Triggers. Add a collider to the object and add a OnTriggerEnter function. Inside this function you can test, if the object is the right type of object and then react to it. Something like this:

private void OnTriggerEnter(Collider other) {
    if(other.gameObject.CompareTag("Player")) {
        //do stuff
    }
}

You can use OnTriggerExit to react to an object leaving the collider, or OnTriggerStay to act every frame as long as the object intersects the collider.

Alternatively you could write a function to check your surroundings:

private Collider[] CheckProximity(float radius) {
    return Physics.OverlapSphere(transform.position, radius);
}

You can cll this function periodically, either via Update, a Coroutine, or InvokeRepeating:

private IEnumerator CheckProximityCoroutine(float radius, float timeBetweenRepetitions) {
    while(true) {
        Collider[] objectsInProximity = CheckProximity(radius);
        //do stuff with the objects...this could also be done inside the ChekProximity function instead of just returning the objects
        yield return new WaitForSeconds(timeBetweenRepetitions);
    }
}

Don’t listen to that…I was about to compliment you on good practice of keeping private stuff private. [SerializeField] is the correct way of handling these variables.

Forgot to mention: I personally would place this behaviour on the Player, and not on the Objects that should react, so it is called only once, and only objects close to the player have to be checked. You can then call a function on the other object for the reaction. If you want to make it really clean, create an Interface that declares that function. Different objects can then implement that interface and react to the player’s proximity.

public interface IReactor {
   public void ReactTo(Player player);
}

This would then be in the Player script, where you check the objects in the Player’s proximity:

IReactor reactor = other.GetComponent<IReactor>();
if(reactor != null) {
    reactor.ReactTo(this);
}
1 Like

Don’t listen to Piflik. :wink: He’s advocating practices which are good in big complex projects, but which are not the simplest or most beginner-friendly solutions, and will increase your risk of never getting the darn thing to work.

In addition, from a philosophical point of view, it shouldn’t be the player object’s responsibility to tell other objects when it gets close — better to put that behavior in the objects themselves, as you (Samantha) already have it. And you can easily do that by getting a reference to the player (in Awake or Start), and then simply checking the distance with Vector3.Distance.

(Or if it’s the case in your game that only the Y position matters, then you can just check Mathf.Abs(player.transform.y - transform.y)… I don’t know if that’s the case here or not, but it might be.)

One way to tell that this is the “right” design is to ask: what if some objects need to react at a different distance than others? Or if some need to react based on distance, while others react based on Y position, and still others based only on X? Having the player object cast a sphere and notify nearby objects will not work (or at best, will get really messy) under these conditions. But having each object manage its own sensing and reactions, keeps it clean and easy.

But, as @Piflik and I have demonstrated, there is more than one way to skin a cat. Do whatever seems simplest to you and don’t worry too much about what anybody else says (including me!).

2 Likes

Pretty much this. There is no one “right” way to do these things. Whatever gets the job done is all that matters. You can spend all of your time trying to apply so-called “best practices” to your code design and never get anywhere with your project because in many cases it complicates things more than they need to be. As I said earlier, write the code to get it done, and once it’s done you can go back and polish things up if you wish.

3 Likes

Hi all, Wow Unity community is awesome, Thank you all for super awesome support. Thank you @sheepixel @JoeStrout @Piflik and @Dave-Carlile .

With your support i manage to crate this;
for me this is working perfect.

void DistanceCheck(float radius){
        if (wakeUpInDistance) {
            myCollider = Physics.OverlapSphere (this.transform.position, radius,mask);
            foreach (Collider col in myCollider) {
                if (col.gameObject.CompareTag ("Player")) {
                    isPlayerNearby = true;
                }
            }
        }
    }

    void OnDrawGizmosSelected(){
        Gizmos.color = Color.yellow;
        Gizmos.DrawWireSphere (transform.position, wakeUpInn);
    }

But i also found out that i can do this;

public class Distance : MonoBehaviour {

    private Transform t;
    private Transform player;

    public

    // Use this for initialization
    void Start () {
        t = this.transform;
        player = GameObject.FindGameObjectWithTag("Player").transform;
    }
  
    // Update is called once per frame
    void Update () {
        if (player) {
            float dist = Vector3.Distance(player.position, transform.position);

        }
    }
}

Earlier when i tried this Vector3.Distace method, i had this in Update

    void Update () {
        if (player) {
            float dist = Vector3.Distance(player.position, transform.position);
            print ("Player distance is " + dist);
        }
    }

“print” was the reason for framerate dropping. :roll_eyes:
Just like you guys are saying

;):wink:

Anyway so both method is working fine. but iam going to use Physics.OverlapSphere for now.

THank you all for awesome support and i will keep update this thread. Feel free to give more feedback.

Oh yeah! We should have pointed that out — print (or Debug.Log) will really slow your game down if it happens every frame. But it’s a good habit to get object references (like your player field) in Awake or Start anyway.

Great job getting this working. Keep it up! :slight_smile:

2 Likes