UE4 UUserWidget is always changed after restarting UE4 or compile at blueprint editor - unreal-engine4

MyHUD.h
UCLASS()
class FPS_API AMyHUD : public AHUD
{
GENERATED_BODY()
UPROPERTY(EditDefaultsOnly, Category = Gameplay)
class UUserWidget* DefaultWidget;
...
}
I make Blueprint BP_MyHUD extends MyHUD and Widget Blueprint. The problem is, the DefaultWidget in BP_MyHUD is set None after i restart UE4 program or compile using button in toolbar at Blueprint editor. How can i fix the value of DefaultWidget in BP_MyHUD?

By default variables are set to "Private" and thus can't be modified in derived classes.
Try putting this UPROPERTY after you say public: (you could also use protected:)
UCLASS()
class FPS_API AMyHUD : public AHUD
{
GENERATED_BODY()
public:
UPROPERTY(EditDefaultsOnly, Category = Gameplay)
class UUserWidget* DefaultWidget;
...
}
Also I am unsure of the EditDefaultsOnly specifier when it comes to blueprints. My understanding was without
BlueprintReadWrite
You could not edit the variables in blueprints. But if you've been using this with success with other variables it is likely not the problem.

A bit late to the party, but here's the answer:
It's not possible.
Non-BindWidget pointers with EditDefaultsOnly indeed generate a selector in the Details panel, but this selector is not meant to select a widget inside our component's archetype. It's meant to select a widget outside an instance of our component (it also need to be public and maybe a BlueprintReadWrite too). In this case, the value you put in the selector indeed stay across builds.
Sadly, this error-inducing selector appearing anyway means that two things aren't quite working properly around this behaviour :
At the moment UE clears the selector when you're building, it should really display a warning/error explaining why
You shouldn't really be able to put EditAnywhere/EditDefaultsOnly on a non-BindWidget property, only a EditInstanceOnly... yet there's no warning/error either =(
(credits to #Bohdon Sayre from BenUI's discord community for helping me on this one)

Related

Is it a good practice to create a class between my own scripts and mono behavior?

So, I have bound the CombatController to an object called "godObject". In the Start() method, I call init() functions on other classes. I did this so I can control the order in which objects are initialized since, for example, the character controller relies on the grid controller being initialized.
Quick diagram:
-------------------- calls
| CombatController | ----------> CameraController.init();
-------------------- |
| ---> GridController.init();
|
| ---> CharacterController.init();
So, now I have a slight problem. I have multiple properties that I need in every controller. At the moment, I have bound everything to the combat controller itself. That means that, in every controller, I have to get an instance of the CombatController via GameObject.Find("godObject).GetComponent<CombatController>(). To be honest, I don't think this is good design.
My idea now was to create a BaseCombatController that extends MonoBehavior, and then have all other classes like GridController, CharacterController etc. extend the BaseCombatController. It might look like this:
public class BaseCombatController : MonoBehaviour
{
public GameObject activePlayer;
public void setActivePlayer(GameObject player) {
this.activePlayer = player;
}
... more stuff to come ...
}
This way, I could access activePlayer everywhere without the need to create a new instance of the CombatController. However, I'm not sure if this doesn't have possible side effects.
So, lots of text for a simple question, is that safe to do?
I use inheritance in Unity all the time. The trick, like you have in the question, is to allow your base class to inherit from monobehavior. For Example:
public class Base Item : Monobehavior
{
public string ItemName;
public int Price;
public virtual void PickUp(){//pickup logic}
//Additional functions. Update etc. Make them virtual.
}
This class sets up what an item should do. Then in a derived class you can change and extend this behavior.
public class Coin : BaseItem
{
//properties set in the inspector
public override void PickUp(){//override pickup logic}
}
I have used this design pattern a lot over the past year, and am currently using it in a retail product. I would say go for it! Unity seems to favor components over inheritance, but you could easily use them in conjunction with each other.
Hope this helps!
As far as I can see this should be safe. If you look into Unity intern or even Microsoft scripts they all extend/inhert (from) each other.
Another thing you could try would be the use of interfaces, here is the Unity Documentation to them: https://unity3d.com/learn/tutorials/topics/scripting/interfaces if you want to check it out.
You are right that GameObject.Find is pure code smell.
You can do it via the inheritance tree (as discussed earlier) or even better via interfaces (as mentioned by Assasin Bot), or (I am surprised no one mentioned it earlier) via static fields (aka the Singleton pattern).
One thing to add from experience - having to have Inits() called in a specific order is a yellow flag for your design - I've been there myself and found myself drowned by init order management.
As a general advice: Unity gives you two usefull callbacks - Awake() and Start(). If you find yourself needing Init() you are probably not using those two as they were designed.
All the Awakes() are guaranteed (for acvie objects) to run before first Start(), so do all the internal object initialisation in Awake(), and binding to external objects on Start(). If you find yourself needing finer control - you should probably simplify the design a bit.
As a rule of thumb: all objects should have their internal state (getcomponents<>, list inits etc) in order by the end of Awake(), but they shold not make any calls depending on other objects being ready before Start(). Splitting it this way usually helps a lot

How to create a HyperHTML custom element extended from HTMLButtonElement

I would like to have a semantic named custom element that extends from button: like fab-button
class FabButton extends HTMLButtonElement {
constructor() {
super();
this.html = hyperHTML.bind(this);
}
}
customElements.define("fab-button", FabButton);
Extending for HTMLButtonElement doesn't seem to work.
Is there a way to extend from a non-HTMLElement with the HyperHTML "document-register-element.js"?
Codepen example:
https://codepen.io/jovdb/pen/qoRare
It's difficult to answer this, because it's tough to understand where to start from.
The TL;DR solution though, is here, but it needs a lot of explanations.
Extending built-ins is a ghost in the Web specs
It doesn't matter what WHATWG says, built-ins are a de-facto death specification because Webkit strongly opposed to it and Firefox, as well as Edge, that never even shipped Custom Elements, didn't push to have them neither.
Accordingly, as starting point, it's discouraged to extend built-ins with Custom Elements V1 specification.
You might have luck with V0 though, but that's only Chrome API and it's already one of those APIs created to die (R.I.P. WebSQL).
My polyfill follows specs by definition
The document-register-element polyfill, born with V0 but revamped with V1, follows specifications as close as possible, which is why it makes extending built-ins possible, because WHATWG still has that part in.
That also means you need to understand how extending built-ins works.
It is not by defining a simple class that extends HTMLButtonElement that you get a button, you need to do at least three extra things:
// define via the whole signature
customElements.define(
"fab-button",
FabButton,
{extends: 'button'}
);
... but also ... allow the polyfill to work
// constructor might receive an instance
// and such instance is the upgraded one
constructor(...args) {
const self = super(...args);
self.html = hyperHTML.bind(self);
return self;
}
and most important, its most basic representation on the page would be like this
<button is="fab-button">+</button>
Bear in mind, with ES6 classes super(...args) would always return the current context. It's there to grant super constructors didn't return other instances as upgraded objects.
The constructor is not your friend
As harsh as it sounds, Custom Elements constructors work only with Shadow DOM and addEventListener, but nothing else, really.
When an element is created is not necessarily upgraded yet. in fact, it won't be, most likely, upgraded.
There are at least 2 bugs filed to every browser and 3 inconsistent behaviors about Custom Elements initialization, but your best bet is that once connectedCallback is invoked, you really have the custom element node content.
connectedCallback() {
this.slots = [...this.childNodes];
this.render();
}
In that way you are sure you actually render the component once live on the DOM, and not when there is not even a content.
I hope I've answered your question in a way that also warns you to go away from custom elements built-ins if that's the beginning of a new project: they are unfortunately not a safe bet for the future of your application.
Best Regards.

GWT Deferred binding failed for custom class: No class matching "..." in urn:import:

I am developing a couple of custom widgets that I would like to be able to use with UiBinder. Unfortunately I keep wasting my life away with chasing down the following error:
No class matching "..." in urn:import:...
This seems to be the catch-all exception that is thrown any time there is any error in the class that prevents the GWT compiler from processing it. This includes anything in the class's entire dependency tree.
To save myself and anyone of you who is running into the same issue some time and pain, let's compile a list here of the most unexpected and hard to find causes for this. I'll start with my latest one, which has made me decide to post this here.
I was using a CellList thusly:
private static RelationshipViewerUiBinder uiBinder = GWT.create(RelationshipViewerUiBinder.class);
#UiField(provided=true)
CellList<String> prioritisedDisplay;
public RelationshipViewer() {
prioritisedDisplay = new CellList<>(new TextCell());
initWidget(uiBinder.createAndBindUi(this));
}
note the Java 7 style <> on the CellList. Despite my IDE's protestations to the contrary, it turns out you DO need to explicitly say CellList< String> in that new call, or it wont compile and all you get is the above mentioned error. Thanks by the way, the existance of this question prompted me to scrutinise my code and probably saved me a couple of hours! This fixed it:
private static RelationshipViewerUiBinder uiBinder = GWT.create(RelationshipViewerUiBinder.class);
#UiField(provided=true)
CellList<String> prioritisedDisplay;
public RelationshipViewer() {
prioritisedDisplay = new CellList<String>(new TextCell());
initWidget(uiBinder.createAndBindUi(this));
}
I had written a component that used the GWT JSON functionality, but hadn't imported com.google.gwt.json.JSON into the module.
Thanks to your message here, this was only 2 hours down the drain...
I wrote a helper-class that this widget uses somewhere deep inside its dependency tree.
For this helper-class, I told Eclipse to auto-generate the hashCode() and equals(...) functions. The class contained a field of type double, for which Eclipse generates code that uses Double.doubleToLongBits().
Turns out GWT does not implement this method on its version of Double. But of course, neither does Eclipse detect this as a possible compile-error, nor does it cause any issues in Dev Mode if I use the widget inside the GWT-App's Java code rather than inside UiBinder.
3 hours down the drain... Great... Yay for helpful error messages.
UPDATE:
As of GWT 2.5.0 (RC1) GWT now supports Double.doubleToLongBits() rendering this particular error obsolete, but the general error mechanism of a missing JRE emulation remains and will probably manifest itself in a similarly unhelpful way.
I was trying to use a GwtQuery DragAndDropCellTree in a UiBinder .ui.xml, which was impossible as DragAndDropCellTree has no zero-arg constructor.
See more details

Why can't I have static public fields in my managed beans?

I just started using the Netbeans 7.1 beta and it is calling out errors of a type which I have never seen before. Specifically:
A managed bean with a public field should not declare any scope other than #Dependent.
The fields it is complaining about are public static final. I can understand the restriction on non-static fields, but I can't think of a good reason this would not be allowed for a static field. Unfortunately I use a lot of them since I don't like having constants in my code.
I note that even though I get the red dot in the margin in the editor, the maven-driven build still works and GlassFish still runs my application the way I would expect.
So what is my denoument on this issue? Am I going to have to move my static fields elsewhere or is there another way of handling this?
Quoting the javax.enterprise.inject package javadocs:
If a managed bean has a public field, it must have scope #Dependent.
But I do agree wih #BalusC that if this compiles, Netbeans should report it as Warning (does it?).
Anyway, are those constants really part of the API? I mean, do you access they anywhere else but within their own classes? If not, reduce visibility to private. (If you just need to access the constants from the view you can also create accessors for the private constant). If yes, I would suggest you to move them somewhere else anyway.
Public fields (static or not) aren't proxyable - that's why they can only be dependent scoped. To work around this you obviously can access them through getter methods.

Prism 4.0 : Overriding InitializeShell() Method

I've been going through the documentation for creating Prism applications and setting up the Shell seems to be split into 2 methods, CreateShell() and InitializeShell()
For CreateShell I simply have:
protected override DependencyObject CreateShell()
{
return ServiceLocator.Current.GetInstance<Shell>();
}
The documentation says that code is needed in the IntializeShell() method to ensure it is ready to be displayed. The following is given as an example:
protected override void InitializeShell()
{
Application.Current.MainWindow = (Window)this.Shell;
Application.Current.MainWindow.Show();
}
I have noticed however that if I omit the first line and just call the Show() method it seems to work (MainWindow already appears to have Shell assigned to it). Can you tell me why this is the case, and why we still need to explicity set the MainWindow property here?
Also as I did not specifically register Shell to an interface within the container, how is it able to resolve Shell in CreateShell()?
Question 1: Why does just calling Show() seem to work and why is Application.Current.MainWindow seem to be populated?
There are a few things you should check here. In a typical WPF application, the type for the main window can be specified in the App.xaml. If it is specified, WPF will instantiate one of those for you. This is not desirable because WPF won't use your container to instantiate your shell and any dependencies won't be resolved.
When you run that first line of code in InitializeShell, you'd be replacing the WPF-instantiated Shell object with the one you manually instantiated.
I looked at the code for the MEF and Unity bootstrappers and I don't see anywhere that MainWindow is being set, but I don't know if you might have customized the base bootstrappers, so that's something else to look for.
Show() works because you are simply showing the window you instantiated and the WPF-instantiated one isn't shown. This is my theory, but without seeing your code, it'd be tough to say for sure.
Question 2: How can Unity resolve something that hasn't been registered?
Unity can always resolve a concrete type, regardless of registration. It cannot resolve non-concrete classes that haven't been mapped to a concrete type. This is why Resolve<Shell> works, but Resolve<IMyInterface> doesn't unless you register a type.