• Advertisement
  • Popular Tags

  • Popular Now

  • Advertisement
  • Similar Content

    • By Brandon Marx
      Hello forum,
      I have some decent amount of experience in Unity making games for Software Engineering projects in college, these were very specific projects however and I still am fairly new to building games. I wanted to make a game that uses the shadows of objects for collision detecting (i.e. shooting a gun at a characters shadow causes that character damage. What is the best engine to do this in (game will be 3D), and does anyone have any advice on how to approach this concept? I consider myself fairly experienced in programming, but game dev is just an entirely different beast.
    • By juicyz
      Hey all,
      I've been slowly working on my game called AotW for a while now.  I have come to the conclusions that it would be nice to cooperate with 1 or 2 others to help finish it.  Ive been trying to keep my GDD up to date with my ideas and development so that would give a better overview of the game when the time comes.  Currently I have a basic skeleton of the RPG elements needed but everything can still be discussed and talked about and we can transform my idea to something the group likes.
      The premise of the game is a Diablo-like procedurally generated map with RPG elements that include sockets, inventory, classes, abilities, crafting, loot, items, sockets, and enchanting.  This will be done in a 2D iso view as I can't do 3D art and I enjoy 2D games a lot.
       
      I don't plan on releasing this as this is more of a hobby project for me and I have a full-time job.  Though I'd like to start putting more hours into development and having others definitely will be motivation.  I also want to be able to say I have finally "finished" a game idea to some degree.  If the time comes and we want to release it, then we can go ahead and do so but that's not my purpose or plan. 
       
      Discord:
      Juicyz#3683
       
       
      Thanks,
      Juicyz
    • By Arnold // Golden Donkey Productions
      Hi, I've been working on this issue for a while and haven't yet found an answer.
      Does anyone know the best way to convert unity's LAT & LONG into a vector 3 position that I could use in a virtual world (if it's even possible). 
      Thankyou in advance
    • By wobbegong_
      I am taking an absolute beginner's game development course and we have just finished game jams in small groups. Our current assignment is to get feedback from people working in any aspect of game development. I would very much appreciate any feedback! The game is up on itchi.io (sound warning) https://wobbegong.itch.io/zombie-shooter It's essentially a very basic PvE.
      I also have some things I'm wondering about, but you don't necessarily have to answer these. 
      1. Do you have any tips on working with physics? My group wrestled a bit with Rigidbody physics not totally working the way we wanted to -- jumping ended up kind of floaty and inclines seem to mess up movement. Alternatively... how can I build terrains with depth that won't result in wonky physics?
      2. How can I keep up the level of challenge in an interesting way as the player progresses through the waves?
      3. What are some of your personal guidelines for creating title screens?
      Thank you very much in advance!
    • By ethancodes
      I'm having a weird issue with detecting a collision. I've tried everything I could find online but nothing seems to work. I have a brick object. It has a 2D Collider attached and I have also attached a 2D Rigidbody on it. I also have an EndScreen 2D Collider. The EndScreen 2D collider is tagged with "EndScreen". I am trying to detect when a brick collides with the end screen collider and simply print "game over" in the console. 
      This is my current code for this part of the program, it is attached to the bricks:
      void OnCollisionEnter (Collision2D collision) { if (collision.gameObject.tag == "EndScreen") { Debug.Log("Game over"); } } Several things have happened depending on the set up. If I have the rigidbody 2D set as static, my ball object can still collide with the bricks, but I get no Log message. If I set it to Kinematic or Dynamic, I get absolutely no interaction between the ball and the bricks, and nothing when the bricks pass through the collider. I have tried to set the collider to a trigger and use OnTriggerEnter2D, no change. I have tried to put the rigidbody on the EndScreen object and tried to set it's body type to all 3 settings, no change. The only thing I can think of that I have not done is put the script on the EndScreen object and switch the tag to the bricks. The reason I have not done this is because I will have several types of bricks, some of which will have different tags. 
       
      Please tell me somebody can see what I'm doing wrong here, because I'm losing my mind over something I feel should be ridiculously simple. Thanks.
  • Advertisement
  • Advertisement
Sign in to follow this  

Unity Singleton and template Error (C++)

This topic is 937 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, First of all thank you for taking time to help.

I recently started playing around with templates and singletons. I'm trying to make something like Unity's Debug.Log but in C++. Starting with simple things like cout. Unfortunately I got stuck and with all the googling I can't seem to find how to solve this issue without not making class singleton. Maybe there is better way of doing this?

 

//Console.h

#pragma once
#include <iostream>

class Console
{
private:
	Console() {}
	~Console() {}
public:
	static Console& instance()
	{
		static Console INSTANCE;
		return INSTANCE;
	}

	template <class T>
	void Print(T arg);

};

//Console.cpp

#include "Console.h"

template <class T>
void Console::Print(T arg)
{
	std::cout << arg.c_str() << std::endl;
}

//main.cpp

#include "Console.h"
int main(int argc, char *argv[])
{
	Console::instance().Print(5);
	return 0;
}

The error is:

Error 1 error LNK2019: unresolved external symbol "public: void __thiscall Console::Print<int>(int)" (??$Print@H@Console@@QAEXH@Z) referenced in function _main E:\WORK\InLine2D\InLine2D\InLine2D\main.obj InLine2D
Error 2 error LNK1120: 1 unresolved externals E:\WORK\InLine2D\InLine2D\Debug\InLine2D.exe 1 1 InLine2D
 
Edited by Konrad Jablonski

Share this post


Link to post
Share on other sites
Advertisement
Unless you explicitly list out all template instantiations, you cannot separate the template into header and source files.

See also: Why can’t I separate the definition of my templates class from its declaration and put it inside a .cpp file?


That aside, you shouldn't use globals because blah blah blah.

EDIT:
SeanMiddleditch has a valid point Edited by fastcall22

Share this post


Link to post
Share on other sites

Unless you explicitly list out all template instantiations, you cannot separate the template into header and source files.

See also: http://www.parashift.com/c++-faq/templates-defn-vs-decl.html

 

Thank you, this makes much more sense now. I swear I had it in one place at one point, but I was getting other errors and thought it was because of that. Just changed it to one file and it's all working now. It's my first time using templates by the way, trying to learn more C++.  Thank you.

Edited by Konrad Jablonski

Share this post


Link to post
Share on other sites


The singleton, a type that can only have one instance ever created, where attempting to create more than one is forbidden by code, that is something to avoid. Even on consoles still a terrible idea. Even for logging where some people suggest it is good, it is a terrible idea: I've worked on plenty of projects where I wanted a private logging system.


A well-known instance, sometimes implemented as pointers within a globally readable data structure, is sometimes a compromise made in coding design.

These well-known instances are NOT singletons (you can create multiple instances if needed) and they are not globals (statically allocated objects), but they are dynamically allocated objects with well-known pointer locations, and they come with strict rules about who can use them for what. These also need to have carefully reviewed, vigorously enforced policies to ensure they are not misused, treating them as short-lived constants in almost all places, with well-defined times of when they can change, such as outside of Update() loops.

Sometimes these well-known instances are managed through a single global object that is nothing more than a bunch of pointers. So you could access it through ::Systems.audio->method(), but there are some big concerns about it. If you are careful that they are mutable and immutable at the right times -- that is they are not modified by using them and that they are only modified at specific times, then it can sometimes work out.

The worst bugs are the ones where those values are modified at the wrong time or by systems unknown. Without warning the behavior of the game is suddenly different, and you cannot find who modified what, when, or why. Suddenly a state was set or a value was modified, and you don't know which of the many systems that could have modified it did so in the wrong spot. Those are nightmares, and the reason globals and mutable shared state are considered terrible design generally.

Share this post


Link to post
Share on other sites

These well-known instances are NOT singletons


I appreciate the distinction and I agree with frob.

I'm used to using "singleton" in a sense that is probably not the same as what the Gang of Four originally described it as. smile.png

See the service locator pattern (also also here) for a better description of what I usually call a "singleton" and what (I think) frob is talking about.

Share this post


Link to post
Share on other sites
For further example, the "singletons" I prefer look something like this:

class IResourceMgr {
public:
  virtual ~IResourceMgr() = default;

  static IResourceMgr& Instance();
  static void ResetInstance(std::unique_ptr<IResourceMgr> instance = nullptr);

  virtual Load() = 0;
  virtual Foo() = 0;
  virtual Bar() = 0;
};
Most user code accesses the above just like the regular singleton pattern prescribes (hence why I call it such), but you can still control the lifetime.

You can pass around any sort of IResourceMgr as you see fit (if you need local temporary, for example), you are still in absolute control of lifetime, you can override the implementation for mocks and testing, and you can select to use a stack-based approach (PushInstance and PopInstance, roughly) when it makes sense to do so.

Share this post


Link to post
Share on other sites

Just be aware, service locators and well-known instances can be a source of nasty bugs and serious design flaws.

 

The pattern introduces quite a lot of coupling. The coupling makes it more difficult to reuse code, where passing a parameter would have allowed reuse. The coupling has a high risk of violating several SOLID principles, it generally breaks Open/Closed, and has a high risk of breaking interface segregation and dependency inversion, but smarter developers will follow them by policy.

 

The key feature that absolutely must be followed if you want to preserve your sanity is that their behavior and use must be immutable. Any of the services being referenced must not be liable to change. They absolutely cannot change while they are in use. Functionality they control should be gated (both by policy and code rules) to prevent inappropriate changes.

 

It is generally best to pass parameters directly to methods rather than rely on these tools. There are usually better design decisions away from the patterns but those better solutions require more parameters, more thought, more insight, and more time to implement.

 

 

 

Again, the service locator / well-known instance pattern is NOT A GOOD DESIGN generally.  It is an unfortunate compromise taken when design is bad, when other programmers incorrectly coupled features, and when you cannot take the time to break the couplings properly.  It should not be the first tool you reach for. It is an unfortunate crutch, a compromise made due to tight deadlines and the sad reality that too much code, both design and implementation, seriously stinks. 

 

It is not a thing to be proud of.  It is a thing that you are best removing from the code as quickly as possible.  It is a code smell, a technical debt, not a point of glory.

Share this post


Link to post
Share on other sites

It is not a thing to be proud of.  It is a thing that you are best removing from the code as quickly as possible.  It is a code smell, a technical debt, not a point of glory.


And here's where I disagree. That kind of purity sounds nice on paper but is academic and just doesn't work in practice. Down that path lies passing 60 parameters to constructors and grotesque contortions just to avoid using a global here and there. All of your code because harder to read, harder to understand, and harder to maintain.

Software inherently relies on layered services. Your OS syscalls are, for all intents and purposes, services/singletons. Your hardware is a service. When you build layered software you add more of your own. There's a point at which software design and implementation simply gets more manageable when you assume layer A sits on top of layer B and don't force a decoupling where there _is_ an intrinsic and unavoidable coupling; good use of globals/singletons/services can accomplish that with no _actual_ problems (despite all the hypothetical ones you might come up with).

Dogmatic application of pithy principles gets you nowhere. At least, nowhere you want to be. I've been there. smile.png

Share this post


Link to post
Share on other sites

I have to agree with Sean here, I am seriously tired of dealing with the cognitive overhead of dependency injection frameworks that have me forced to pass the same damn object around everywhere because it's sufficiently basic and low-level that everything needs it, and at the end of the day it's still a global because everything everywhere has a reference to the exact same object. Things are just as bad as with a global, except now I have a dependency injection framework with it and my code's simple logic is obscured by a weird meta-language to describe its relationship with other simple dependencies (parameter-passing in constructors/factories, annotations, XML dependency trees; pick your poison). I do not see a problem with having genuine services as long as their interface is sane, nor am I against explicitly codifying abstract dependencies when it makes sense and adds value. I have a brain and my colleagues do as well, and at work I find that most of it is being used working with against "modern" design patterns and contorting straightforward code to fit someone else's idea of "decoupled code" instead of actually implementing business logic, and probably producing far more bugs as a result. As everything else in life, design principles become bad and dangerous when taken in excess. If in doubt, stop and think.

 

Anyway frob I found it interesting that you used the word "generally" followed by an unconditional statement. What in your opinion would be an uncommon use case where a singleton or service locator would be a sensible design choice?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement