As was foretold, we've added advertisements to the forums! If you have questions, or if you encounter any bugs, please visit this thread: https://forums.penny-arcade.com/discussion/240191/forum-advertisement-faq-and-reports-thread/
We're funding a new Acquisitions Incorporated series on Kickstarter right now! Check it out at https://www.kickstarter.com/projects/pennyarcade/acquisitions-incorporated-the-series-2

Game Dev - Unreal 4.13 Out Now!

18182848687100

Posts

  • RendRend Registered User regular
    The basic difference between 2d and 3d mode in unity is that 2d mode only utilizes the X and Y axes for physics, and makes it easy to ignore the Z axis in game logic. That's the vast majority of it, from what I understand.

    Morninglord
  • MorninglordMorninglord I'm tired of being Batman, so today I'll be Owl.Registered User regular
    sweet

    (PSN: Morninglord) (Steam: Morninglord) (WiiU: Morninglord22) I like to record and toss up a lot of random gaming videos here.
  • GlalGlal AiredaleRegistered User regular
    Sprites in Unity (and any 3d accelerated engine) are just textures on polygons anyway. In my Unity messing about my "sprite" character was literally a box with a texture on the front-facing side.

    Morninglordamnesiasoft
  • VicVic Registered User regular
    edited February 2016
    I'm afraid I'm still struggling with my very basic attempts at making a hover-over button. I'm sorry about wasting people's time again, but some help would be appreciated.

    My goal is fairly simple. I have an object with a piece of text attached, called tooltip and tooltext. The script I'm using is attached to a button called Button, that should bring and reveal the tooltip and change its text on mousehover.

    Code:
    using UnityEngine;
    using UnityEngine.UI;
    using System.Collections;
    
    public class testscript : MonoBehaviour
    {
        Text tootex = GameObject.Find("tooltext").GetComponent<Text>();
        GameObject tooobj = GameObject.Find("tooltip");
        RectTransform butrec = GameObject.Find("Button").GetComponent<RectTransform>();
        Image tooima = GameObject.Find("tooltip").GetComponent<Image>();
        Text butttex = GameObject.Find("Text1").GetComponent<Text>();
    
        void Start()
        {
        }    
    
    	void Update ()
        {
    	}
    
        public void onClick()
        {
            butttex.text = "Click Text";
        }
    
        public void onHover()
        {
            tootex.text = "Tooltip Text";
            float posx = butrec.rect.position.x + butrec.rect.width;
            float posy = butrec.rect.position.y - butrec.rect.height;    
            tooobj.transform.localPosition = new Vector3(posx, posy, 0);
            tooima.enabled = true;
            tootex.enabled = true;           
        }
    
        public void onLeave()
        {
            tooima.enabled = false;
            tootex.enabled = false;
    
        }
    }
    

    Yes, I know it is filthy and awful. As a note, I got the tip yesterday that I could refer to the gameobject the script is attached to it by simply excluding it from a query, replacing

    RectTransform butrec = GameObject.Find("Button").GetComponent<RectTransform>();

    with

    RectTransform butrec = GetComponent<RectTransform>();

    However that doesn't work. I get the error message "A field initializer cannot reference the non-static field, method or property 'Component.GetComponent<RectTransform>()' ". The same thing happens when I declare a gameobject and then try to pull a component out of it like Khavall showed earlier (like Rigidbody rb = thisObject.GetComponent<Rigidbody>();)


    The main problem is that even without relying on that I'm currently getting all of these error messages, as well as occasional complaints about not correctly referencing an instance of an object. The annoying thing is that they aren't referencing any particular lines in the code, they just highlight the Button object when I click on them, and I have no idea where else I would put the find functions.
    UnityException: You are not allowed to call this function when declaring a variable.
    Move it to the line after without a variable declaration.
    If you are using C# don't use this function in the constructor or field initializers, Instead move initialization to the Awake or Start function.
    testscript..ctor ()

    Find can only be called from the main thread.
    Constructors and field initializers will be executed from the loading thread when loading a scene.
    Don't use this function in the constructor or field initializers, instead move initialization code to the Awake or Start function.

    ArgumentException: Find can only be called from the main thread.
    Constructors and field initializers will be executed from the loading thread when loading a scene.
    Don't use this function in the constructor or field initializers, instead move initialization code to the Awake or Start function.
    testscript..ctor ()
    In other words, nothing is fucking working, and I'm currently feeling like the worst attempt at a hack unity programmer.

    Vic on
  • KhavallKhavall British ColumbiaRegistered User regular
    edited February 2016
    It's a pretty easy fix. Basically, what the error is saying is that you're trying to set an object reference in the scene, when the script doesn't even know what the scene is or what's in it.

    You can set variables in the constructor(int i = 0;), but not objects, because of just something about how Unity interacts with objects.

    Easiest fix in the world is just change the beginning of the code to:
    public class testscript : MonoBehaviour
    {
         Text tooTex;
         GameObject tooObj;
         RectTransform butRec;
         Image tooIma;
         Text butTex;
    
         void Awake(){ 
        tooTex = GameObject.Find("tooltext").GetComponent<Text>();
        tooObj = GameObject.Find("tooltip");
        butRec = GameObject.Find("Button").GetComponent<RectTransform>();
        tooIma = GameObject.Find("tooltip").GetComponent<Image>();
        buttTex = GameObject.Find("Text1").GetComponent<Text>();
     }
    
    // and then the rest
    

    It's just one of those things about where and when unity is doing stuff. Awake() basically is "Before anything starts happening, once the object is initialized, do this", similar to Start(), but before Start().

    (I realize I camel-cased because I'm so used to doing so, you can do it without the camelcasing if you want.

    Khavall on
  • VicVic Registered User regular
    That fixed it, thanks again!

  • LorkLork Registered User regular
    Just a clarification, you can play with objects in constructors as much as you want as long as you don't try to use special Unity functions like GameObject.Find(). Vic's problems specifically were 1. Trying to use the non static function GameObject.GetComponent() outside of a method and 2. Trying to use GameObject.Find() outside of a method, which is static but can't be used for reasons explained by the error message. If those reasons are flying over your head, it doesn't really matter too much as long as you follow their advice and put it in Awake() or Start() instead like Khavall has done.

    Steam Profile: Lork
  • VicVic Registered User regular
    edited February 2016
    Mo days, mo problems. Description in spoiler if anyone wants to help

    Note: I promise I do actually google extensively before asking here, I 'm just finding the resources on unity fairly unhelpful so far.

    My game will include lots of random characters, all of which need basic character sheets. In order for the whole game to be able to easily access this information I figured I should input it into a List, since I've seen so many people advice against the use of arrays. The problem is that I don't really understand how to access a list from outside scripts. Example:
    using UnityEngine;
    using System.Collections;
    
    public class list1
    {
    
        public static string name;
    
        public list1(string newName)
        {
            name = newName;
        }
    }
    
    using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;
    
    
    public class creator1 : MonoBehaviour
    {
        public static List<list1> testlist = new List<list1>();
        void Start()
        {
    
            testlist.Add(new list1("Roger"));
        }
    
    }
    
    using UnityEngine;
    using UnityEngine.UI;
    using System.Collections;
    
    public class reader : MonoBehaviour {
    
        public Text testtext;
    	
    	public void onClick()
        {
            testtext.text = creator1.testlist[0].name;
        }
    }
    

    This gives me the error message "Member 'list1.name' cannot be accessed with an instance reference; qualify it with a type name instead."

    Vic on
  • LorkLork Registered User regular
    edited February 2016
    Why are you making name and testlist static? That's what's causing your issue. You should probably read up on what the static keyword does and when you should use it.

    Lork on
    Steam Profile: Lork
  • VicVic Registered User regular
    edited February 2016
    Lork wrote: »
    Why are you making name and testlist static? That's what's causing your issue. You should probably read up on what the static keyword does and when you should use it.

    That seems to be it. I'm finding it really hard to wrap my head around static. I've been using it to be able to refer to a variable from a different script without having to point to a specific instance. Now that I think about it it makes sense that the name variable within the list1 script would have to be non-static for this to work though. I'll keep reading!

    Edit: I think Unity might have finally broken me.

    Vic on
  • RendRend Registered User regular
    Vic wrote: »
    Lork wrote: »
    Why are you making name and testlist static? That's what's causing your issue. You should probably read up on what the static keyword does and when you should use it.

    That seems to be it. I'm finding it really hard to wrap my head around static. I've been using it to be able to refer to a variable from a different script without having to point to a specific instance. Now that I think about it it makes sense that the name variable within the list1 script would have to be non-static for this to work though. I'll keep reading!

    Basically the answer is that for variables/fields, normal non-static ones belong to the instance of the object, and static ones belong to the object type itself. For that reason you access them like this:
    class HasAStatic{
      public static int myStaticInt;
      public int myNormalInt;
    }
    
    function(){
      HasAStatic obj = new HasAStatic();
      obj.myNormalInt = 1;
      HasAStatic.myStaticInt = 1;
    }
    

    Generally speaking you should avoid static variables except in certain specific circumstances, because it is much easier to overuse the static keyword than it is to properly use it. If you know for certain that you will need one and only one instance of a class (like a GameState master class of some sort) you can use a static variable to create a Singleton, like so:
    
    public class GameState : MonoBehaviour{
      private static GameState instance = null;
      
      void Awake(){
        if(instance == null){
          instance = this;
          //Other initializations
        }
      }
    
      public void doAThing(int param){
        //Whatever
      }
    
      public static GameState getInstance(){
        return instance;
      }
    }
    
    ...
    
    function(){
      GameState.getInstance().doAThing(1);
    }
    

    There are a few reasons to have static variables in your classes (and many to have static methods) but definitely be sure to understand the implications of the keyword, because marking too much stuff static will definitely bite you down the line. Overuse of static can be a major architectural frailty.

  • VicVic Registered User regular
    edited February 2016
    Good god I can feel my head trying to implode when I am reading that code. Not that it's unclear or bad, just that I'm overloaded by reading tutorials and failing to program for about 16 hours this weekend (and also absolutely awful at understanding gameobject-variable-class-keyword interaction.)

    I very much appreciate the help, and I'm sure my brain will be able to parse it eventually.

    I unfortunately need to ask one more question:

    Edit: I may have isolated the issue, lets see if I can solve it.
    Edit2: Narrowed it down, but still don't know whats wrong
    The purpose of this List is to contain character information, including name and stats. In order to see how well it is doing I have set up a basic character sheet that shows me the name and stats, allowing me to browse through a set of 50 pre-generated characters. The problem is that it only shows me one set of stats.

    The list and declaring class look like this:
    using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;
    
    public class cData
    {
        public static List<cid> cid = new List<cid>();
    }
    
    public class cid
    {
        // Names
        public string name = new string;
        // Stats
        public int[] statLvl;
    
        public cid(string newName, int[] newStats)
        {
            // Names
            name = newName;
    
            // Stats
            statLvl = newStats;      
            Debug.Log(statLvl[3]);
        }
    }
    

    Using the Debug log code above I have confirmed that after running my character generator the list cid contains 50 members, with statLvl[3] containing values between 2 and 4. However when I try to extract these variables for different characters (different members of the list) I always get the same number. The call function I'm using is basically this:
    strlvl.text = cData.cid[sctemp.ccid].statLvl[3].ToString();
    
    Where sctemp.ccid is a global static int (the current character id) variable that I currently use basic buttons to increase and decrease, which I have confirmed to work by successfully extracting the name field with "nametext.text = cData.cid[ccid].name[1];"

    Vic on
  • LorkLork Registered User regular
    edited February 2016
    strlvl.text = cData.cid[sctemp.ccid].statLvl[3].ToString();
    
    Can you show us how this is being called? Are you sure it's being called again to update the text every time you change the current id? If you replace it with a Debug.Log() does a new log entry pop up every time you press the button?

    Also, while it doesn't appear to be the cause of your issue right now, I think you should try to avoid using static altogether until you have a better understanding of the basics. If there are things you don't know how to do without it, you're better off pushing through and learning how you're actually supposed to do that stuff. You're liable to get into a lot of trouble later down the line if you continue using them the way you are now, and besides, you'll probably find it a lot easier to get things done once you fill those gaps in your knowledge.

    Lork on
    Steam Profile: Lork
  • VicVic Registered User regular
    edited February 2016
    Lork wrote: »
    strlvl.text = cData.cid[sctemp.ccid].statLvl[3].ToString();
    
    Can you show us how this is being called? Are you sure it's being called again to update the text every time you change the current id? If you replace it with a Debug.Log() does a new one pop up every time you press the button?

    Also, while it doesn't appear to be the cause of your issue right now, I think you should try to avoid using static altogether until you have a better understanding of the basics. If there are things you don't know how to do without it, you're better off pushing through and learning how you're actually supposed to do that stuff. You're liable to get into a lot of trouble later down the line if you continue using them the way you are now, and besides, you'll probably find it a lot easier to get things done once you fill those gaps in your knowledge.

    It's in the Update void, which I realise is incredibly inefficient but haven't figured out the preferable alternative to yet.
    using UnityEngine;
    using UnityEngine.UI;
    using System.Collections;
    
    public class scr_strmain : MonoBehaviour {
    
        public Text strlvl;
        public Image barimg;
        
        public void onClick()
        {
            
        }
    
        void Update ()
        {
            strlvl.text = cData.cid[sctemp.ccid].statLvl[3].ToString();
            barimg.rectTransform.sizeDelta = new Vector2(15 * cData.cid[sctemp.ccid].statLvl[3], 16);
        }
    }
    
    I got this script working when the statLvl was a simple int array, this is basically just a rework of that with a List.

    As for the point about statics, I just don't understand what my options are when I want to access a function in a script attached to a different object without using the drag and drop function of Unity.

    Like, I have a newChar function within a script attached to a gameobject I may or may not know the name, location or nature of. This script and gameobject is unique, there will never be another instance of it anywhere in the game. Now I want to run this function from an entirely different script in a different part of the game. What would be a preferable option to making the function static?

    I guess the fundamental problem might be the fact that I don't understand how to work with instances at all.

    Edit: Just checked, cData.cid[sctemp.ccid].statLvl[3] indeed always pulls the same number.

    Vic on
  • rembrandtqeinsteinrembrandtqeinstein Registered User regular
    Got another fun Unity question here...

    how would I go about having a Unity application listen for local http requests?

    My current project is a Twitch chat bot/overlay controller https://trello.com/b/sVNI1VeQ/beardbot

    The Unity window is displayed as the stream overlay. I'm investigating options for how to make an "offstream" UI for it.

    The latest mad science is to create an HTTP server within the Unity application that serves up a web application (or if I want to get even more ridiculous an android application) and that application is used for configuration and control of the bot.

    I saw the HTTPListener object in .NET 2 but that apparently only works on Windows. For extra difficulty I'm developing on OSX

  • LorkLork Registered User regular
    edited February 2016
    Vic wrote: »
    It's in the Update void, which I realise is incredibly inefficient but haven't figured out the preferable alternative to yet.
    Optimization is really not something you need to be worrying about right now, but since you asked: A great time to change the text is when you click the button that changes the value. Assuming the button is set up right, any code in that onClick() method you already have in there should run every time you click the button.
    As for the point about statics, I just don't understand what my options are when I want to access a function in a script attached to a different object without using the drag and drop function of Unity.

    Like, I have a newChar function within a script attached to a gameobject I may or may not know the name, location or nature of. This script and gameobject is unique, there will never be another instance of it anywhere in the game. Now I want to run this function from an entirely different script in a different part of the game. What would be a preferable option to making the function static?

    I guess the fundamental problem might be the fact that I don't understand how to work with instances at all.
    The basic ingredients you need to access a member of an instance (be it a variable or a method) are the public keyword, which marks it as being accessible to other classes, and a reference to that instance. If you're writing a method for a certain class and you want to do something to the public members of an instance of another class, or even a different instance of the same class, what you need to do is get your hands on a reference to that other instance. There are a million and one ways to pass a reference from one object to another, and which one to use depends entirely on context, so your example is way too broad to give any specific advice.

    Can you give an example where a specific instance of a class needs to perform a specific task that would require it to communicate with something else? That way I can at least tell you what I'd do in that situation.

    Lork on
    Steam Profile: Lork
  • VicVic Registered User regular
    edited February 2016
    Lork wrote: »
    Vic wrote: »
    It's in the Update void, which I realise is incredibly inefficient but haven't figured out the preferable alternative to yet.
    Optimization is really not something you need to be worrying about right now, but since you asked: A great time to change the text is when you click the button that changes the value. Assuming the button is set up right, any code in that onClick() method you already have in there should run every time you click the button.
    As for the point about statics, I just don't understand what my options are when I want to access a function in a script attached to a different object without using the drag and drop function of Unity.

    Like, I have a newChar function within a script attached to a gameobject I may or may not know the name, location or nature of. This script and gameobject is unique, there will never be another instance of it anywhere in the game. Now I want to run this function from an entirely different script in a different part of the game. What would be a preferable option to making the function static?

    I guess the fundamental problem might be the fact that I don't understand how to work with instances at all.
    The basic ingredients you need to access a member of an instance (be it a variable or a method) are the public keyword, which marks it as being accessible to other classes, and a reference to that instance. If you're writing a method for a certain class and you want to do something to the public members of an instance of another class, or even a different instance of the same class, what you need to do is get your hands on a reference to that other instance. There are a million and one ways to pass a reference from one object to another, and which one to use depends entirely on context, so your example is way too broad to give any specific advice.

    Can you give an example where a specific instance of a class needs to perform a specific task that would require it to communicate with something else? That way I can at least tell you what I'd do in that situation.

    My best attempt:

    The player will be able to hire new staff, for example guards. When the player enters the hire UI a function needs to create a pool of characters for the player to hire from. A script determines a random number of character to generate, then calls on the static void charGen() located in the character generator script (which is technically a class, right?), which generates these characters by adding them to the cdat list, then returns their character ID's so that the character hire menu can properly display their stats.

    That.... is an awfully convoluted answer, I realize. That main point is that literally dozens of scripts may need to generate new characters, and hundreds will need to access the character stat data, and it seems insane to manually set up links between them whether through drag and dropping in the Unity UI or by passing references along them.



    I have further narrowed down the problem in my stat display code from earlier. It turns out that the problem lies in the simple line "statLvl = newStats;"

    To clarify, newStats is an int array with seven components, and is one of the inputs in the class creator function. When I try to assign all the stats at the same time using "statLvl = newStats;" and then call them using "strlvl.text = cData.cid[sctemp.ccid].statLvl[3].ToString();" I get the same value for every member of the list.

    When I instead assign strength as a single int, using the line "statStrLvl = newStats[3];", I get different values for the members of the list when I call them using "strlvl.text = cData.cid[sctemp.ccid].statStrLvl.ToString();"

    I tried assigning the stats one at a time using lines like "statLvl[1] = newStats[1]; statLvl[2] = newStats[2];" and so on, but that just broke the script, returning
    NullReferenceException: Object reference not set to an instance of an object
    cid..ctor (System.String newName, System.Int32[] newStats) (at Assets/cdat.cs:27)
    scg.newChar (Int32 cnumin) (at Assets/scg.cs:26)
    sctemp.Start () (at Assets/sctemp.cs:16)
    

    So something about the way I'm using arrays in a List of Classes is obviously busted, but I'm not sure what. I could technically live without them and have all the data I need as single integers, but I would have to write out like 200+ of them by name. I have confirmed that newStats actually does have seven components, by the by.


    Edit: And again, a huge thanks to everyone who's taken the time to help me with my dumbass questions. I realize that I have dived into the deep end with a game that is far too ambitious for my first real attempt at unity programming, but thanks to you guys I'm still making progress.

    Vic on
  • RendRend Registered User regular
    edited February 2016
    Vic wrote: »
    My best attempt:

    The player will be able to hire new staff, for example guards. When the player enters the hire UI a function needs to create a pool of characters for the player to hire from. A script determines a random number of character to generate, then calls on the static void charGen() located in the character generator script (which is technically a class, right?), which generates these characters by adding them to the cdat list, then returns their character ID's so that the character hire menu can properly display their stats.

    That.... is an awfully convoluted answer, I realize. That main point is that literally dozens of scripts may need to generate new characters, and hundreds will need to access the character stat data, and it seems insane to manually set up links between them whether through drag and dropping in the Unity UI or by passing references along them.

    So, you have a few different components here. The key question you should be asking yourself is "whose job is it to do this?"

    Or, more specifically: Whose job is it to generate new characters? You have a UI component that displays the current list of characters. Is it the job of this piece to create a new character? Well, no, probably not, because its job is not to CREATE, but to DISPLAY. The phrase "dozens of scripts may need to generate new characters" is a huge red flag. Dozens of scripts may directly cause new characters to be created, but deciding when to create new characters should probably be the domain of one and only one of your scripts.

    One way to go about this might be to have a class both create new characters and keep the list of currently created characters. This would be appropriate for a list which was always randomized and which automatically filled itself to a certain amount. You'd simply request the list, and before serving it, this class would fill it up.

    The way you're describing is actually pretty close to the "Factory" pattern which is how I would recommend you do it, but with a few key differences. For one thing, your CharacterFactory class should not have
    static void charGen()
    it should be:
    static Character createCharacter()

    Because "Create a character" and "add this character to the list" are two different tasks. You don't want one command to do two different things. It's like if you double clicked a folder on your desktop and it both opened the folder and also executed the first file in it. What? No, you didn't ask for that second thing.

    You can have a function in your list called void addRandomCharacter() which generated a random character using the character factory and then added it to its own list, but the difference is that both of those steps are inherent to the task of adding a random character (first, create a random character, then add it to the list). The task of creating a character does not imply that it is added to any list anywhere.

    Usually in a factory class all of the functions are static. Note, however, that this is NOT so that you can access them from other scripts, but because the act of creating new things based on a set of parameters is usually stateless. Meaning, it doesn't matter what state the factory object is in, the creation process of the factory is the same no matter what. As a result, you don't even need an instance of the class to accomplish the task.

    (I would write more but this is already a wall of text and I have a meeting to go to)

    Rend on
    Jacoby
  • zagdrobzagdrob Registered User regular
    edited February 2016
    Vic wrote: »
    Lork wrote: »
    Vic wrote: »
    It's in the Update void, which I realise is incredibly inefficient but haven't figured out the preferable alternative to yet.
    Optimization is really not something you need to be worrying about right now, but since you asked: A great time to change the text is when you click the button that changes the value. Assuming the button is set up right, any code in that onClick() method you already have in there should run every time you click the button.
    As for the point about statics, I just don't understand what my options are when I want to access a function in a script attached to a different object without using the drag and drop function of Unity.

    Like, I have a newChar function within a script attached to a gameobject I may or may not know the name, location or nature of. This script and gameobject is unique, there will never be another instance of it anywhere in the game. Now I want to run this function from an entirely different script in a different part of the game. What would be a preferable option to making the function static?

    I guess the fundamental problem might be the fact that I don't understand how to work with instances at all.
    The basic ingredients you need to access a member of an instance (be it a variable or a method) are the public keyword, which marks it as being accessible to other classes, and a reference to that instance. If you're writing a method for a certain class and you want to do something to the public members of an instance of another class, or even a different instance of the same class, what you need to do is get your hands on a reference to that other instance. There are a million and one ways to pass a reference from one object to another, and which one to use depends entirely on context, so your example is way too broad to give any specific advice.

    Can you give an example where a specific instance of a class needs to perform a specific task that would require it to communicate with something else? That way I can at least tell you what I'd do in that situation.

    My best attempt:

    The player will be able to hire new staff, for example guards. When the player enters the hire UI a function needs to create a pool of characters for the player to hire from. A script determines a random number of character to generate, then calls on the static void charGen() located in the character generator script (which is technically a class, right?), which generates these characters by adding them to the cdat list, then returns their character ID's so that the character hire menu can properly display their stats.

    That.... is an awfully convoluted answer, I realize. That main point is that literally dozens of scripts may need to generate new characters, and hundreds will need to access the character stat data, and it seems insane to manually set up links between them whether through drag and dropping in the Unity UI or by passing references along them.

    I'm not going to say that I do things the best or simplest way...but for something like this, I would use the Singleton Pattern.

    Your class will look something like this:
        public class CharacterPooler : MonoBehaviour {
            private static CharacterPooler _instance;
            public static CharacterPooler instance {
                get {
                    if (_instance == null)
                        _instance = GameCharacter.FindObjectOfType<CharacterPooler>();
                    return _instance;
                }
            }
    		
    		[Serialize Field]
    		private List<Character> _characterList;
                    public List<Character> CharacterList {get {return _characterList;}}
    		
    		public Character GetRandomCharacter() {
    			return _characterList[Random.Range(0, _characterList.Count)];
    		}
    	}		
    

    Create a single 'GameManager' object in your scene, and attach this script to it. You can then call this script from anywhere using the below syntax:
    Character randomCharacter = CharacterPooler.instance.GetRandomCharacter();
    

    Then, if you create a 'Character' class like the below one, you can populate the _characterList through the editor. Personally, I would create the below Character class as a ScriptableObject, which I could then treat like prefabs and drag-and-drop into the _characterList field.
    public class Character {		
    		[Serialize Field]
    		private string _characterName;
    		public string CharacterName { get {return _characterName;}}
    	}
    		[Serialize Field]
    		private int _hitPoints;
    		public int HitPoints { get {return _hitPoints;}}
    	}
    
    

    Again, I don't know how 'best practice' this is or if it's a really terrible way of doing things, but it's been working for me (using ScriptableObjects) to load all the different ship and item types into my game.

    EDIT - you can also use the below code to get your full list, and populate your Character Selector GUI interface, etc.
    List<Character> allCharacters = CharacterPooler.instance.CharacterList;
    

    zagdrob on
    Rend
  • VicVic Registered User regular
    That makes sense, and I think I'm slowly working my way toward that sort of thinking. My current setup contains the following:

    The class "cid", that will eventually contain all the variables a character needs
    The function class "cDat" that declares the static character list using "cid"
    The character generator function, that contains a static character generator currently designated static void charGen() (that you have suggested I should rename static Character createCharacter() ). This function actively populates the list using the Add function, because it seemed to make little sense to route that through a "middle man".
    A character list populator function that simply calls on the character generator function above 50 times.

    The only components of this that are static are the character generator functions (+ variables) and the list hosted in cDat.

  • RendRend Registered User regular
    Random sidebar: you should be more verbose with your names! CharacterData, CharacterList, and CharacterStats are more readable than cid and cDat. Not only for people helping you but also for you when you come back to modify stuff.

    LaCabraEvilOtakuzagdrobKhavall
  • VicVic Registered User regular
    edited February 2016
    @zagdrob
    I have seen the singleton pattern mentioned before, and I thank you for your noble efforts in trying to describe it, but I'm still too confused by it to dare try to integrate it into my current project. It's certainly something I'll try very hard to understand in the future!

    @Rend
    That is certainly good advice, I shall endeavor to be less lazy about this in the future

    I ended up replacing all of the arrays in my character info class, and as a result I now have a functional (though super-basic) character generator and character sheet! My week one goal for the project is complete only one day late, which I consider a huge success!

    Vic on
    Rend
  • LaCabraLaCabra MelbourneRegistered User regular
    Crossposting from the Half-Life thread, HammUEr has progressed to the point where you can do this in like half an hour:

    https://www.youtube.com/watch?v=bldDKTdMTbQ&amp;feature=youtu.be

    GlalHallowedFaithIzzimachMNC DoverKoopahTroopah
  • HandkorHandkor Registered User regular
    That is awesome.

  • MvrckMvrck Dwarven MountainhomeRegistered User regular
    Rend wrote: »
    Random sidebar: you should be more verbose with your names! CharacterData, CharacterList, and CharacterStats are more readable than cid and cDat. Not only for people helping you but also for you when you come back to modify stuff.

    Listen to the man everyone. It may take a little extra typing now, but you'll be glad you did when you have to rebuilt or add onto the functions using those variables in 8 months and you're sitting there going "what the fuck does this even do?"

    KashaarLaCabraKhavallOatsEvilOtakuTofystedethSageinaRage
  • GlalGlal AiredaleRegistered User regular
    I'm having an issue in UE4 where my scene elements look dimmer, more washed out than their textures/sprites. The material they use is set to unlit, so lighting conditions shouldn't really affect them, any idea what might be going wrong?
    The textures do have SRPG toggled on (which seemed to cause this problem when they switched how gamma worked on legacy textures a while back) and I tried creating a post processing volume in the level to override any default settings levels might come with (though, I'm not sure I did it right. I just dragged one into the level and set it Unbound, no idea if more was needed to make it active).

    Unfortunately as this could be caused by anything from texture settings, material settings, camera settings to post processing settings it's proving difficult to pin down.

  • KashaarKashaar Low OrbitRegistered User regular
    Glal wrote: »
    I'm having an issue in UE4 where my scene elements look dimmer, more washed out than their textures/sprites. The material they use is set to unlit, so lighting conditions shouldn't really affect them, any idea what might be going wrong?
    The textures do have SRPG toggled on (which seemed to cause this problem when they switched how gamma worked on legacy textures a while back) and I tried creating a post processing volume in the level to override any default settings levels might come with (though, I'm not sure I did it right. I just dragged one into the level and set it Unbound, no idea if more was needed to make it active).

    Unfortunately as this could be caused by anything from texture settings, material settings, camera settings to post processing settings it's proving difficult to pin down.

    Sounds like tone mapping could be the culprit. Check (or add) a post-processing volume and play with the settings! There might also be a setting in Project Settings to disable it entirely, but I'm not sure.

    If detail gets washed out, Temporal Anti-Aliasing might be the cause. You can switch the AA method to FXAA in postprocess volumes, see if that changes anything.

    Indie Dev Blog | Twitter | Steam
    Unreal Engine 4 Developers Community.

    I'm working on a cute little video game! Here's a link for you.
    Glal
  • KhavallKhavall British ColumbiaRegistered User regular
    Mvrck wrote: »
    Rend wrote: »
    Random sidebar: you should be more verbose with your names! CharacterData, CharacterList, and CharacterStats are more readable than cid and cDat. Not only for people helping you but also for you when you come back to modify stuff.

    Listen to the man everyone. It may take a little extra typing now, but you'll be glad you did when you have to rebuilt or add onto the functions using those variables in 8 months and you're sitting there going "what the fuck does this even do?"

    Yeah I was going to mention this too.

    You really lose nothing than a couple of keystrokes having longer names, and it's so much clearer to figure out what's going on.


    I mean there's a limit, you don't want to have void ThisOneMakesTheCharactersAndThenAssignsThemTheirVariablesLikeDataAndStatsAndHealth(), but void GenerateCharacters() is way more clear both for other people to read, and also easier to keep track of as the project increases in size and you might leave some stuff behind and come back a week later to a function and what does GenC() even do.

    KashaarElvenshaeEvilOtakuCalica
  • GlalGlal AiredaleRegistered User regular
    Kashaar wrote: »
    Glal wrote: »
    I'm having an issue in UE4 where my scene elements look dimmer, more washed out than their textures/sprites. The material they use is set to unlit, so lighting conditions shouldn't really affect them, any idea what might be going wrong?
    The textures do have SRPG toggled on (which seemed to cause this problem when they switched how gamma worked on legacy textures a while back) and I tried creating a post processing volume in the level to override any default settings levels might come with (though, I'm not sure I did it right. I just dragged one into the level and set it Unbound, no idea if more was needed to make it active).

    Unfortunately as this could be caused by anything from texture settings, material settings, camera settings to post processing settings it's proving difficult to pin down.

    Sounds like tone mapping could be the culprit. Check (or add) a post-processing volume and play with the settings! There might also be a setting in Project Settings to disable it entirely, but I'm not sure.

    If detail gets washed out, Temporal Anti-Aliasing might be the cause. You can switch the AA method to FXAA in postprocess volumes, see if that changes anything.
    Okay, I've managed to minimise it, but it's still slightly darker than original textures. In post processing I had to set Contrast to 0, Crush Shadows and Crush Highlights to 1 and Vignette Intensity to 0.

    As said, it's still slightly darker, but unlike before the difference is only noticeable if you flick between them quickly, rather than the colours being obviously washed out.

  • KashaarKashaar Low OrbitRegistered User regular
    Glal wrote: »
    Kashaar wrote: »
    Glal wrote: »
    I'm having an issue in UE4 where my scene elements look dimmer, more washed out than their textures/sprites. The material they use is set to unlit, so lighting conditions shouldn't really affect them, any idea what might be going wrong?
    The textures do have SRPG toggled on (which seemed to cause this problem when they switched how gamma worked on legacy textures a while back) and I tried creating a post processing volume in the level to override any default settings levels might come with (though, I'm not sure I did it right. I just dragged one into the level and set it Unbound, no idea if more was needed to make it active).

    Unfortunately as this could be caused by anything from texture settings, material settings, camera settings to post processing settings it's proving difficult to pin down.

    Sounds like tone mapping could be the culprit. Check (or add) a post-processing volume and play with the settings! There might also be a setting in Project Settings to disable it entirely, but I'm not sure.

    If detail gets washed out, Temporal Anti-Aliasing might be the cause. You can switch the AA method to FXAA in postprocess volumes, see if that changes anything.
    Okay, I've managed to minimise it, but it's still slightly darker than original textures. In post processing I had to set Contrast to 0, Crush Shadows and Crush Highlights to 1 and Vignette Intensity to 0.

    As said, it's still slightly darker, but unlike before the difference is only noticeable if you flick between them quickly, rather than the colours being obviously washed out.

    It could also be the auto-exposure/eye adaptation doing that. If you set the min and max both to 1.0, it is effectively disabled.

    Indie Dev Blog | Twitter | Steam
    Unreal Engine 4 Developers Community.

    I'm working on a cute little video game! Here's a link for you.
    MachwingGlal
  • KhavallKhavall British ColumbiaRegistered User regular
    Ok, I really need to just spend a day cleaning up the shit that has risen up in the past week.

    Like I'm pretty sure that since the MusicManager tells each tower to advance every time a sixteenth note would be played, and the advance() code can just have the firing logic and can keep track of which sixteenth that tower is on in relation to the next note, and the total number of sixteenths is entirely irrelevant, I can just, like... totally drop the towers coroutines that have been handling their firing logic/music, which simplifies the tower code to like 20 lines.

    But I've now got broken prototypes built upon broken prototypes built upon prototypes that all share some variables and maybe use some of the same stuff, that are a nightmare to read through.

    I guess this is what my "Get stuff working, and then endlessly iterate to refine" programming style has wrought.

  • RendRend Registered User regular
    Khavall wrote: »
    and also easier to keep track of as the project increases in size and you might leave some stuff behind and come back a week later to a function and what does GenC() even do.

    "Might" is the wrong word for this
    "Will" is a better word

    You absolutely will lose track of any project of nontrivial size because any project of nontrivial size will be too big and too complex to fit in your head at once. This was something most of the students had trouble getting their head around when I was a teacher's assistant in university. The projects they were doing that took like 4-6 hours to complete are all extremely trivial. The practices they were learning were not to assist them in mapping their homework, but for when they start doing other stuff that takes them ten, one hundred, maybe even one thousand times longer.

    And, before you say anything I know this is probably what you meant, but I get soapbox'y about topics I encountered as a teacher's assistant. I've seen a LOT of novice and intermediate level programmers in university just skip out on this sort of discipline because they're holding the info they need in their heads right now and so obviously having an integer named fuckin' "hamburger" is fine because it's hilarious and you remember what it's actually for.

    I'm not making that last part up.

    NaxEvilOtakuTofystedethSageinaRage
  • MvrckMvrck Dwarven MountainhomeRegistered User regular
    Rend wrote: »
    Khavall wrote: »
    and also easier to keep track of as the project increases in size and you might leave some stuff behind and come back a week later to a function and what does GenC() even do.

    "Might" is the wrong word for this
    "Will" is a better word

    You absolutely will lose track of any project of nontrivial size because any project of nontrivial size will be too big and too complex to fit in your head at once. This was something most of the students had trouble getting their head around when I was a teacher's assistant in university. The projects they were doing that took like 4-6 hours to complete are all extremely trivial. The practices they were learning were not to assist them in mapping their homework, but for when they start doing other stuff that takes them ten, one hundred, maybe even one thousand times longer.

    And, before you say anything I know this is probably what you meant, but I get soapbox'y about topics I encountered as a teacher's assistant. I've seen a LOT of novice and intermediate level programmers in university just skip out on this sort of discipline because they're holding the info they need in their heads right now and so obviously having an integer named fuckin' "hamburger" is fine because it's hilarious and you remember what it's actually for.

    I'm not making that last part up.

    Don't even get me started on this. I took over a departmental website for a while when their web developer quit, until they could hire a replacement. The main javascript file read like an index of knowyourmeme with function names and variables.

  • MachwingMachwing It looks like a harmless old computer, doesn't it? Left in this cave to rot ... or to flower!Registered User regular
    Kashaar wrote: »
    If detail gets washed out, Temporal Anti-Aliasing might be the cause. You can switch the AA method to FXAA in postprocess volumes, see if that changes anything.

    yes turn off temporal AA immediately it is fucking garbage
    it real bad

    l3icwZV.png
  • LaCabraLaCabra MelbourneRegistered User regular
    nah it's fine fuck the police

    KoopahTroopahKashaar
  • HandkorHandkor Registered User regular
    Kashaar wrote: »
    Glal wrote: »
    Kashaar wrote: »
    Glal wrote: »
    I'm having an issue in UE4 where my scene elements look dimmer, more washed out than their textures/sprites. The material they use is set to unlit, so lighting conditions shouldn't really affect them, any idea what might be going wrong?
    The textures do have SRPG toggled on (which seemed to cause this problem when they switched how gamma worked on legacy textures a while back) and I tried creating a post processing volume in the level to override any default settings levels might come with (though, I'm not sure I did it right. I just dragged one into the level and set it Unbound, no idea if more was needed to make it active).

    Unfortunately as this could be caused by anything from texture settings, material settings, camera settings to post processing settings it's proving difficult to pin down.

    Sounds like tone mapping could be the culprit. Check (or add) a post-processing volume and play with the settings! There might also be a setting in Project Settings to disable it entirely, but I'm not sure.

    If detail gets washed out, Temporal Anti-Aliasing might be the cause. You can switch the AA method to FXAA in postprocess volumes, see if that changes anything.
    Okay, I've managed to minimise it, but it's still slightly darker than original textures. In post processing I had to set Contrast to 0, Crush Shadows and Crush Highlights to 1 and Vignette Intensity to 0.

    As said, it's still slightly darker, but unlike before the difference is only noticeable if you flick between them quickly, rather than the colours being obviously washed out.

    It could also be the auto-exposure/eye adaptation doing that. If you set the min and max both to 1.0, it is effectively disabled.

    I've had a washed out texture problem once during an LudumDare Jam, I used Bitmap2Material and it produced 16bit png instead of 8-bit. When importing 16bit images they appeared washed out in the world. I resaved them as 8bit to solve the problem.

  • GlalGlal AiredaleRegistered User regular
    It's definitely a post-processing issue here, it goes away in editor mode if you toggle off tone mapping. There have been people complaining about it since 2014, it's a consequence of certain post-processing steps being taken to prevent colours getting blown out in certain conditions and so on. Which is fair enough, but it'd be nice if they also offered an easy way to disable it entirely for those that either care about colour reproduction or, like myself, work with an unlit scene that doesn't need protecting from lighting anomalies.

    I've gotten it to the point where it's not really an issue past my artist side going "but mah assets! They're not perfect!". This is an interesting read into someone's attempts to work around it. Especially the part where they looked at the post-processing code and applied the reverse of what the code is doing to their textures to restore them that way, that's just great. It's from 2014, so the steps might no longer be correct, but it's still neat.

  • DarkMechaDarkMecha The Outer SpaceRegistered User regular
    I was working on refining my local avoidance steering AI today and was just not feeling my design. I decided to research how other people might have approached it and came across this simple video:

    https://www.youtube.com/watch?v=tFKzJhn22Bs

    Amazing! This is the kind of behavior I'm looking for! So I thought about how they were achieving this and quickly realized that they were simply measuring if the angle between the detected object and the ship was positive or negative. This gives an easy way to know which side the thing was on compared to the ship and thus steer in the opposite direction (right if negative, left if positive) until the raycast is no longer intercepting an object. I think it will need abit more stuff to combine with my other nav system along with some tweaking to avoid edge case scenarios that might get it stuck but this *should* work and is quite simple.

    Steam Profile | My Art | NID: DarkMecha (SW-4787-9571-8977) | PSN: DarkMecha
    Kashaar
  • GlalGlal AiredaleRegistered User regular
    Man, having "fun" with transparency sorting issues in UE4. Long story short, tilemaps are meant for building tile-based 2d levels and provide multiple (flat) layers with custom inter-layer spacing, allowing your sprite to walk on top of a middle layer with background and foreground layers around them.

    Unfortunately if you're using a transparent material for both your sprite and your tilemap (and you have to, if your tile assets are translucent PNGs and you want the edges to display nicely, rather than being rounded to a hard pixel) then the depth sorting fucks up and treats the entire tilemap object, all the layers at once, as having the same sort depth, making your sprite either draw in front or behind the entire stack, depending on whether your ground layer was closer to the top or the bottom.


    Rather obnoxious, but it doesn't seem like there is an easy solution for it. For now I'll just have to work on the tilemaps using a Masked material, then when I want the pretty final version duplicate the tilemap, delete one's foreground layer(s) and the other one's background layers. The problem only crops up when the two transparent layers are part of the same object, so that at least works around that.
    Either that or build the levels in an external tile editor and then import them, buuuuuuut that seems like faf I could do without.

  • ZekZek Registered User regular
    edited February 2016
    Man sometimes my brain is so fickle when it comes to motivation and I don't even know why. A couple weeks ago I found out Cookie Clicker 2.0 was out and I've been going down that utterly pointless rabbit hole again - what I've discovered is that it seems to occupy the same space in my brain that my game development hobby does. I had trained myself to take those "I'm bored at my computer right now" moments as an impetus to do some dev work instead of aimlessly browsing YouTube or something, but now I feel the pull of tabbing over to Cookie Clicker to check my progress and buy some more upgrades, and after that the moment is gone. It's like my mind only has so much capacity for multitasking, and having a timesink like that floating on the edge of my awareness at all times pushes it just over the edge.

    Anyway I resolved to free myself from the idle game curse ASAP by way of heavy automation, so I will put it to bed once and for all any day now.

    Edit: Screw it, I deleted my save. This far and no further. Fuck you, lizard brain.

    Zek on
    Kupi
Sign In or Register to comment.