How do I extend the ThirdPersonCharacterControl standard assets to use new buttons?
I've imported the Standard Assets for CrossPlatformInput, ThirdPersonCharacter and ThirdPersonUserControl into my 3D project and they work fine. I'd like to extend it to have actions other than Run, Jump, and Crouch. What is the best practice for extending this functionality? For example, if I want to add a "Pick Up" button which picks an item up off the ground at the current position, I can either add that directly to the ThirdPersonUserControl script, I can copy the source into a new script in my own namespace, or I can create a new component script just for the abilty to pick up items. I would think that option #3 is the best option, but I won't be able to check for the presence of that component from within the Characters.ThirdPerson or CrossPlatformInput namespaces (these are handled in the .CSharp.Plugins solution, not my project's solution.
I have a feeling my question just stems from not understanding how those solutions interact. If nothing else, I can just grab the source and put it in my own files, but I feel like it's better to reference the original script and build off it with my own components if possible. Thanks for any and all advice!
Answer by Statement · Oct 31, 2015 at 11:25 PM
What is the best practice for extending this functionality?
I don't think there's any accepted "best practice" to extend that particular component. I haven't used the standard assets much at all, but in general simply subclassing the existing type would be one way to add more features to an existing class. Of course the parent class may have private functions and what not to make the whole thing a bit harder or impossible, but it could be something to try first. That way you don't have to change existing code, but I have a feeling you ain't going to get away that easy.
Components are nice and separates concern nicely. Figure out what it is that the scripts already do and which part of their job you want to extend. For example, picking stuff up probably involves picking objects in the scene, displaying UI, animating character, stopping movement, playing sounds etc. Perhaps the last three is something that the 3rd person character would do, picking objects in the scene something that user control delegates to a raycaster. In that scenario it sounds like you want to modify user control/3rd party character and possibly add a raycaster component to the mix. It all depends on how tightly they need to interact with each other.
I would think that option #3 is the best option, but I won't be able to check for the presence of that component from within the Characters.ThirdPerson or CrossPlatformInput namespaces (these are handled in the .CSharp.Plugins solution, not my project's solution.
That's just because they sit in a special folder called "Standard Assets" which is compiled separately so UnityScript developers can use the scripts as well. If you rename that folder or move the files to a different folder, they'll be in the same assembly as the rest of your scripts.
I have a feeling my question just stems from not understanding how those solutions interact.
Well, have a look at Special Folders and Script Compilation Order. Basically Standard Assets types cannot depend on your types, but your types can depend on Standard Asset types. If you want, you could add an interface or a base class to Standard Assets, add modifications to Standard Assets to give it the ability to indirectly call your scripts. Your scripts can implement or inherit from those interfaces or base classes. That way they can talk between each other without Standard Assets directly depending on the types in your project.
If nothing else, I can just grab the source and put it in my own files, but I feel like it's better to reference the original script and build off it with my own components if possible.
Well, to be honest I think you'll find situations where you want to meddle with what goes on inside a method call. In those cases you'll want to modify the source. What is your concern about modifying the existing code? That in case someone drops an update of the source you'll have pain merging? Or something else? I wouldn't treat the standard assets as a holy grail, but a more interesting example than what they got on the website. The authors cannot predict how users want to extend on it and so there may be design flaws you want to correct to tailor for your specific project.
Thanks @statement, this is a great reply and answers every part of my question. I think for my purposes I will just create a new class and start modifying the source. I know that in future Unity updates that 'CrossPlatformInput' set of standard assets is likely to change anyway.
To answer your questions in your answer, my concern about changing the source was simply that I'd be going down a rabbit hole trying to solve a problem that already had a more elegant solution. I think you've summed it up well here that there are a few avenues I could go down but none of them are the established right answer.
Also, the resources about special folders and script compilation order are great, I didn't realize this was how the Standard Assets were treated, appreciate it.
I think it would be a very interesting exercise to extend functionality without touching the existing standard assets code. You could try and see what kind of issues you end up with, and ponder if there is a good way to solve them. Ideally, one shouldn't have to change other classes from a software design point of view. It would be a nice test to see how well they adhere to SOLID, especially the O in SOLID: OCP :)
Unfortunately I haven't messed much with the samples so I don't know how easy they are to work with.
In object-oriented program$$anonymous$$g, the open/closed principle states "software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification";[1] that is, such an entity can allow its behaviour to be extended without modifying its source code.
That said, don't be afraid of gutting things apart to get it to work. But if you want to challange yourself, have a go at it and perhaps write a blog post about how it went and your recommendations.
Your answer
Follow this Question
Related Questions
Character Movement rotates Cinemachine Camera wildly 0 Answers
What is the vr head input for google vr sdk v1.130 0 Answers
What is the issue in this player movement script? 1 Answer
input.getaxis problem 0 Answers
Huge drift Issue with xbox controllers. 0 Answers