Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by spammenao252 · May 17, 2013 at 03:34 PM · c#.netinterop

Simplest way to call c# code from Unity and hook events

I'm trying to create a game that does not rely on a specific game engine for rendering and logic such as range-checking, consider the following simplified example;

 /// <summary>
 /// All non-engine specific api methods/events etc.
 /// </summary>
 public interface IApiBase
 {
     void Start();
     void PerformPlayerAttack();
     event Action<IDamageableEntity> EntityCreated;
 }

 /// <summary>
 /// Unity specific API Methods etc.
 /// </summary>
 public interface IUnityApi : IApiBase
 {
     void SetPlayerLocation(UnityEngine.Vector3 v);
 }

 static class Bootstrapper
 {
     /// <summary>
     /// We'll somehow need to get Unity to call this so it can 
     ///   hook the events and call 'Start()' and other methods
     ///   throughout the game.
     /// </summary>
     public static IUnityApi CreateApi()
     {
         return new UnityApi(new ServiceFactoryUnityImpl(), new Vector3SrvcUnityImpl());
     }
 }

 //Relevant entity part for this question
 public interface IDamageableEntity : IMovableEntity
 {
     event Action Damaged;
 }

So bottom line;

 I need to call Bootstrapper.CreateApi(); from within Unity 
 Hook the 'EntityCreated' event
 Call Start() 
 Each time 'EntityCreated' fires, create a model for it in the gameworld and hook the Entity's 'Damaged' event
 Each time that fires, execute the relevant model's 'takehit' animation or w/e it is we're doing

In addition to this, it'll need to call PerformPlayerAttack(); on left mouse button (or w/e) and SetPlayerLocation(); when the player model moved, passing the model's position as a parameter.

Preferrably, it'd be a two-way street so the c# application can correct the model's position after lag/possible hack attempts etc.

I'm running .NET 4.0 - any ideas?

Comment
Add comment · Show 4
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image nventimiglia · May 21, 2013 at 09:39 PM 1
Share
  1. Your reinventing the world, not a good idea.

  2. $$anonymous$$ore moving parts = more chances for it to break.

  3. If you want to separate your concerns, try mvvm.

  4. Not enough code to really understand what your trying to do.

avatar image Benproductions1 · May 22, 2013 at 01:16 AM 0
Share

I have another question: WHY are you doing this?

avatar image spammenao252 · May 22, 2013 at 04:10 PM 0
Share

@Benproductions: Why not? $$anonymous$$eeping things seperate makes it easier to swap out certain parts. Anyway, I figured out that most of what I want to do can be done using mono on .NET 3.5 - what bugs me though is that even then some features of .NET35 aren't supported. As an example, I can't use Linfu for dynamic proxy creation because then Unity throws a typeloadexception.. is there any way around such restrictions? The only thing I can think of is creating a proxy over TCP so I can run a mono .NET 4.0 application seperately but considering all the serialization that would probably hurt performance quite a bit.

avatar image Benproductions1 · May 24, 2013 at 01:05 PM 0
Share

@spammenao252 Because I want to finish a project within a reasonable amount of time, ins$$anonymous$$d of writing an underlying system that I would hardly ever use... How many times are you really going to swap out an entire system in a game? (especially an entire game engine?) How much time would this actually save?
Anyway... thats just my opinion... you can obviously do whatever, and to be honest this does sound kind of cool XD

3 Replies

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by Tomer-Barkan · May 22, 2013 at 09:03 PM

Unlike what some others wrote, I agree that separating your logic from the engine that runs it, as much as possible, is good practice. For example, you wouldn't access a database directly from your code, you would use a class and methods that translate your database queries to specific queries for your chosen database. Then, if you would want to change database provider, you only have to change one level of your code, the one that translates high level queries to specific database implementation.

That said, take into account that development time will be much longer, since you will have to create a generic API for every action that you perform in unity, and then the unity specific implementation of this API. So if you change engine, you will only have to re-create the engine specific implementation of the API, but the API itself and the game logic will remain untouched.

My recommendation: 1. Create your own classes per game object that handle the actual game logic, decision making, etc. 2. Have a layer of intermediate classes, that translate high-level commands (for example, move object 10 meters right) to unity-specific commands (transform.translate() in the given example). 3. The intermediate classes will need to have reference to actual unity objects, and perform unity-specific operations. They will implement generic (non unity specific) interface, which will be the interface between your logic classes and these intermidiate classes 4. Your logic classes will have reference to the interfaces, and use them to perform the actions 5. Your actual unity scripts (attached to actual unity objects) will have very basic functionality, that will instantiate your logic classes, and pass them the relevant parameters and the unity-specific intermediate classes. The unity classes will also call the logic class methods Start(), Update(), etc.

Here's a simple example:

 interface MovementHandler {
     public void MoveObject(Vector3 moveVector); // this is a generic definition of what MoveObject() does - move the object from current position towards moveVector. Not unity specific.
 }

 class UnityMovementHandler : MovementHandler {
     private GameObject object;                        // the unity specific implementation of movement handler needs an actual unity object to move
     
     public UnityMovementHandler(GameObject object) {
         this.object = object;
     }

     public void MovementHandler.MoveObject(Vector3 moveVector) {
         object.transform.position = object.transform.position + moveVector;        // this is the unity specific implementation for moving an object
     }
 }

 class MyPlayer {
     private MovementHandler movementHandler;

     public MyPlayer(MovementHandler movementHandler) {
         this.movementHandler = movementHandler;
     }
     
     public onFrameUpdate() {
         movementHandler.MoveObject(new Vector3 (1, 0, 0));    // move object 1 meter to the right. Independent of engine since it uses the generic version - MovementHandler
     }
 }

 // this is the unity script, which will be created and called by the unity engine. It needs to instantiate and use your unity-independent classes
 class UnityPlayer : MonoBehavior {
     private MyPlayer player;
     
     void Start() {
         MovementHandler moveHandler = new UnityMovementHandler(this.gameObject);
         player = new MyPlayer(moveHandler);
     }
     
     void Update() {
         player.onFrameUpdate();
     }
 }


Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image spammenao252 · May 24, 2013 at 10:44 AM 0
Share

$$anonymous$$udos for understanding what I'm getting at rather than simply nay-saying. I'm still having a couple of issues as described in my comment @ the question but this answers my original question so I'll pick it. Thanks for your time!

avatar image Tomer-Barkan · May 24, 2013 at 01:45 PM 0
Share

@spammenao252: I'm glad my answer helped. I read your comment, and would like to try to answer. Since unity is multi platform (it's code will be run on windows AND linux/$$anonymous$$AC/IOS machines, so it doesn't really use .NET language, it uses $$anonymous$$ONO which is an open source implementation of .NET. Unfortunately, not all of .NET's stuff exist in $$anonymous$$ONO, hence the error you're getting. I can't think of only using $$anonymous$$ONO classes... read here for some more info: http://stackoverflow.com/questions/15924850/unity3d-typeloadexception

avatar image
2

Answer by Jamora · May 22, 2013 at 10:39 PM

Is the goal here to create a game engine that can combine features from other game engines or a game that uses only one engine, but is transferrable to another engine?

In case of the former, I don't think this forum is the right place to ask. The latter, however could (possibly) be accomplished by -creating a wrapper for all classes from Unity that you need

-creating a custom base class that extends MonoBehaviour, which is in turn extended by all your classes

-programming to interfaces instead of the implementation

-instantiating everything from code (apart from one of Unity's own GameObjects that starts the game)

If the game engine is changed, to let the new game engine do all the work, all that needs changing are the wrapper classes and what the base class extends.

Something like this:

public class BaseClass : MonoBehaviour {}

public class GameObjectWrapper {

private GameObject thisGameObject;

public GameObjectWrapper (GameObject newObject){ thisGameObject = newObject;}

}

public class GameObjectWrapperFactory{

public static GameObjectWrapper Create(){ return new GameObjectWrapper(new GameObject());}

}

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image spammenao252 · May 24, 2013 at 10:46 AM 0
Share

I'd upvote this if I could because it answers a couple of questions but it would seem I need more rep to do so.. thanks for your time though! To answer your question, I'm not trying to mix multiple engines together but having a hot-swappable engine is nice but still, it's mostly just to keep things seperated and prevent spaghetti code.

avatar image
0

Answer by tpainton · Feb 08, 2015 at 02:28 PM

Its amazing to me that so many unity programmers really don't understand encapsulation and true object oriented programming. Thanks for this question. It's going to make expansion of my game over time much faster.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

18 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

BindingList could not be found? 2 Answers

how can i use ZipArchive class ,How can i use .net ZipArchive Class 0 Answers

Print JSON to screen as a block of text in unity during runtime 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges