How to set the liquid level for a lava block? Bukkit 1.15.2 plugin - plugins

I'm trying to make it so that any time a player breaks a certain block, lava will be spawned at that block. But i don't want the spawned lava to be a source block. How do i do this? I've tried everything and if there was just one simple solution it would be greatly appreciated.
thanks!

I didn't tried it by myself, but I assume you can place the block and change the BlockData afterwards. Just get the BlockData with getBlockData() cast it to a Levelled and change the level value and assign the Levelled to the block again. Please check out the documentation of Levelled, the value you need to choose isn't intuitive.

As Geist 5000 said:
I didn't tried it by myself, but I assume you can place the block and change the BlockData afterwards. Just get the BlockData with getBlockData() cast it to a Levelled and change the level value and assign the Levelled to the block again. Please check out the documentation of Levelled, the value you need to choose isn't intuitive.
You can modify the BlockData cast it into Levelled and set the level there:
public void setLavaBlock(Location location, int level) {
Block target = location.getBlock();
target.setType(Material.LAVA);
Levelled blockData = (Levelled) target.getBlockData();
blockData.setLevel(level);
target.setBlockData(blockData);
}

Related

What does the query method do in Flutter Flame game and what type is it supposed to be?

I'm trying to get the update function in Flame game to work. I have a global variable called newInstructions that's a list that gets updated by a separate function. I want the update function to check when there's a new addition to the list and call a function (populateInfo) with that list as input. After looking at some of the documentation, I've come up with what I think would be the correct code, but it keeps returning this error:
The method 'query' isn't defined by the type 'List'
I think that part of this might come from my not fully understanding what the update/query methods do. With that, what does the query method do and what type should it be? How would I go about changing my code to fix that error?
Here is the update function that I wrote:
#override
void update(double dt){
final instructions = newInstructions.query<List>();
populateInfo(instructions);
}
With that, what does the query method do and what type should it be?
query is a Flame specific method that is used on the OrderedSet in each component where the children are stored, it is used to get children of a specific type. For example to get all Player components:
children.query<Player>();
How would I go about changing my code to fix that error?
Since you want to react to when something is added the newInstructions list you shouldn't do this check in update since this method runs at least 60 times per seconds, it's better to just react once when there is a new instruction added.
This can be done in a few different ways, you could for example put the newInstructions list in a class that you then have an add method on that both adds the instruction to a list contained within the class, and also calls populateInfo. You could also wrap the list in a ChangeNotifier like this.

MRTK Add ManipulationHandler in C#

I'm attempting to dynamically add Manipulation Events to a ManipulationHandler that is being added to child objects of a parent. The parent object will be what the user is inspecting, but the user will be able to grab parts off of the parent and inspect them more closely. (i.e. you can look at an engine (parent object), but if you want to inspect the pistons (child objects) you can grab them and look at them)
Instead of having to go into every child object and manually add it in Unity I'd like to be able to add the parent object and just procedurally add the ManipulationHandler and ManipulationEvents on start or awake.
So far I have the following code for adding the ManipulationHandler script, but to add the ManipulationEvent I'm not sure how to set up the pointers so I can use the script and function I want from the source:
gameObject.AddComponent<ManipulationHandler>();
ManipulationHandler handler = gameObject.GetComponent<ManipulationHandler>();
ManipulationEvent newevent = new ManipulationEvent();
ManipulationEventData eventdata = new ManipulationEventData();
eventdata.ManipulationSource = gameObject;
The program works when I grab the objects, but I'd like to add manipulation events when I grab them so I can display additional data.
I see there's a getter and setter for Pointer in ManipulationEventData, but I'm not sure how to instantiate IMixedRealityPointer and how to get it to work. I'm also not sure if that's the object I actually need to accomplish what I'd like to accomplish.
I apologize in advance if I've missed something obvious. I'm new to MRTK.
Thanks!
The ManipulationHandler has four callback events among them OnManipulationStarted and OnManipulationEnded you can simply add listeners to. (see UnityEvent.AddListener)
Unless I understood your question wrong you don't have to instantiate any IMixedRealityPointer. You don't create the event data yourself but rather the ManipulationHandler feeds these events with the current event data including the interacting pointer information. The ManipulationHandler uses OnPointerDown and OnPointerDragged and OnPointerUp via the IMixedRealityPointerHandler interface in order to manage the interacting pointers and invokes the according events where needed.
Instead of using AddComponent followed by GetComponent directly store and use the return value of AddComponent which will be the reference of the newly added Component. MRTK also has an extension method
T EnsureComponent<T>(this Component component) where T : Component
so that you can simply use e.g.
var handler = this.EnsureComponent<ManipulationHandler>();
which internally first checks whether the component already exists, and if not it adds it.
Note that in order to enable near interactions you will also need a NearInteractionGrabbable so you should add this one too.
You also will have to make sure that your objects have some sort of Collider attached to the same GameObject as the NearInteractionGrabbable.
...
gameObject.transform.EnsureComponnet<NearInteractionGrabbable>();
var handler = gameObject.transform.EnsureComponnet<ManipulationHandler>();
handler.OnManipulationStarted.AddListener(HandleOnManipulationStarted);
handler.OnManipulationEnded.AddListener(HandleOnManipulationEnded);
...
/// <summary>
/// If you need it later you need to store the pointer since unfortunately in
/// OnManipulationEnded the <see cref="ManipulationEventData.Pointer"/> is null
/// (no idea why they do it this way :D )
/// </summary>
private IMixedRealityPointer _pointer;
private void HandleOnManipulationStarted(ManipulationEventData eventData)
{
_pointer = eventData.Pointer;
// whatever shall happen when manipulation started
}
private void HandleOnManipulationEnded(ManipulationEventData eventData)
{
// whatever shall happen when manipulation ended
}
Note: I am not sure if this thing you are trying to achieve is possible with this architecture ... it is very possible that nesting various ManipulationHanlder leads to strange behavior here and there. Especially very small parts will be almost impossible to grab ...

Is there any way to use AddComponent with a script in Unity if there is no instance of that script in the game yet?

I need a way to add a script to an object that I just Instantiated. Ideally I could just set the script to add in the inspector. The problem is that I can't use
public Component scriptToAdd;
because then I would need to already have an empty object or something with the script on it. While that would work it feels kind of dirty or hackish to make an empty that just stores references to something. Also the point of doing it like this for me is to make it more efficient to swap out different scripts. If I had to swap out a script on an empty and then drag the new one in I'd lose on some of that efficiency I'm after. Thanks for any help.
After you instantiate, you should use the GameObject.AddComponent() Class, to add any component Type you want.
for example, if you want to add a camera to the scene.
void Start () {
GameObject myNewCamera = new GameObject();
//creates an empty game object, you can already attach components to it.
myNewCamera.AddComponent<Camera>();
//adds a component of type Camera
}
You can also use the overloaded constructor
GameObject myNewCamera = new GameObject("my object name", typeof(ScriptToAdd));
GameObject myNewCamera = new GameObject("my object name", typeof(ScriptToAdd), typeof(MoreComponentsToAdd));
Also, you should never be afraid of using an empty GameObject on your scene, for keeping information, references, variable values, saves, or anything really. It doesn't really affect the performance of your game, and you can make your life easy just by having an easy to find tag, such as "Engine".
Then you can access anything just by adding:
GameObject.FindGameObjectWithTag("Engine");
I hope I was able to help you :)
-Noe

Does Unity have a constructor when loading a scene?

I would like to populate the UI when I load a scene, with the correct data, instead of placeholders.
When I call "LoadSceneAsync", what would be the first object that is called, so I can fill the UI label with the correct data? I know that there is a scene GameObject, but I am not sure if that would fit my needs.
I am looking for some sort of constructor, called when a new scene object is loaded; to plug in my setup function.
You say
Indeed I did use "onlevelwasloaded" but the UI element may not be there, ready to go, when I invoke it, which lead to errors
That would be an incredibly sever bug in Unity! :)
Could it be that you are mixing-up Awake and Start somewhere?
One way to think of it is once you call Start, you know all the Awake have already run.
When I call "LoadSceneAsync", what would be the first object that is called, so I can fill the UI label with the correct data
You are still within the same frame.
Once you see LoadSceneAsync you can be absolutely assured everything is Awake 'd.
Or indeed once you use Start you can be absolutely assured everything is Awake 'd.
1) could it be that in some of your UI elements (or whatever) you are doing something in Start which you should do in Awake?
2) if (for some reason) you want to "wait until the next frame", perhaps just during development - then do that, wait a frame. You'll see a flicker, but if that's what you want to do (for some reason) do that.
3) note that if you mean you want to go to the net to get something, well of course you have to wait frames (use Update/coroutine) until the information comes back from the net, obviously. (How else could it be?)
Note that in practice, one should be using UnityEngine.Events.UnityEvent everywhere.
Maybe this is what you are looking for http://docs.unity3d.com/ScriptReference/MonoBehaviour.OnLevelWasLoaded.html
Relying on Unity internal functioning is not always the way to go. Particularly when dealing with RESTApi (which is somehow what you are dealing with here).
You cannot assume one object will be ready before another except if you control it.
Add a Controller script that uses Awake. In the Awake, call all the methods you are needing and use some callback to generate secondary code when primary is ready.
public class MyController: MonoBehaviour{
private ServerRequestController serverCtrl = null;
private UIController uiCtrl = null;
private void Awake(){
serverCtrl = this.gameObject.AddComponent<ServerRequestController>();
uiCtrl =this.gameObject.AddComponent<UIController>();
serverCtrl.GetData(uiCtrl.SetUI);
}
}
public class UIController:MonoBehaviour{
public void SetUI(Data data)
{
SetTopImage(data.topImage);
SetBottomImage(data.bottomImage);
// And so on
}
}
public class ServerRequestController:MonoBehaviour{
public void GetData(Action onCompletion){
// This may be a coroutine if you fetch from server
Data data = GetDataFromSomewhere();
// At this point, your data is ready
onCompletion(data);
}
}
Thanks to this, you are now able to know exactly when a piece of code is ready.

What is the difference between GetComponent<Image> ().enabled and .SetActive (false); in unity

I have been trying to use SetActive () to turn on and off GameObjects.
I couldn't figure it out and ended up using:
GameObject.Find ("ObjectName").GetComponent<Image> ().enabled = false;
to turn off an image.
I am not trying to use the same script to turn off a GameObject that has multiple animations nested inside it.
GameObject.Find ("ObjectName").GetComponent<???> ().enabled = false;
GameObject.Find ("ObjectName").SetActive (false);
I am not sure what goes in the <>, but I have read I can do it with SetActive (), but that doesn't seem to work and gives me an "Object Reference not set to object" error.
So what is the difference between these two and how would I use them properly?
Using GetComponent allows you to enable/disable and interact with specific components on a GameObject.
For example, you may need to disable a GameObject's rigidbody at some point, but you still want that object, and everything else on it to be active. So you could simply say:
GameObject.Find("MyObject").GetComponent<Rigidbody>().enabled = false;
Note that what goes inside the "<>" is the class name of the component you want to interact with.
For example, if you had a script you have written yourself on a gameobject called MyScript, you could grab hold of it like so:
MyScript script = GamesObject.Find("MyObject").GetComponent<MyScript>().enabled = true;
Additionally, another good use of GetComponent is reading information from a script on an object.
For example, if you had a script called Health with a public variable HitPoints on an object, another script could gain access to that information using GetComponent.
if( enemyGameObject.GetComponent<Health>().HitPoints < 0 )
{
enemyGameObject.SetActive(false);
}
Using SetActive will enable and disable a GameObject entirely. This is less expensive than deleting / making a new object, and is thus often used in techniques like Object Pooling.
For example, if you had a GameObject that you needed disabled, but you knew you were going to need it again soon, it is far less expensive to just call
MyGameObject.SetActive(false);
...
MyGameObject.SetActive(true);
Than it is to delete that object entirely, and then make a new one when you are ready for it again.
To add up to the other answers, when a component is disabled it means the MonoBehaviour callbacks are not called anymore. So no Update, FixedUpdate, OnCollisionXXX and so on.
Awake is called when the object is created so it is obviously enabled by default at that stage. Start is called on the first run after Awake. So if you set the component off in Awake, Start will wait until you set it back on from elsewhere.
OnEnable/OnDisable are called when you modify the enabled property.
SetActive works on the GO and is pretty much a shortcut to disable all components at once.
gameObject.SetActive(false);
foreach(var comp in GetComponentsInChildren<MonoBehaviour>()){
comp.enabled = false;
}
those are fairly similar in result (maybe not in efficiency). Actually, when you set a game object on/off, the OnEnable/OnDisable of each component is called. All MonoBehaviour callbacks are not called anymore if you set the object off.
So, the choice is dependent on what you are after, if you wish to disable movement but still see the object and other actions:
GetComponent<Movement>().enabled = false;
if you wish to kill an enemy:
enemy.gameObject.SetActive(false);
Note that even though a component is disable, does not mean you cannot interact with it. You can still manually call any method on it. Consider this:
AnyComponent ac = gameObject.GetComponent<AnyComponent>();
ac.enabled = false;
ac.AnyMethod();
Valid and will do what it is meant to do considering it does not require an Update or a FixedUpdate (Physics action).
A deactivated component cannot be found with GetComponent, you can get it with GetComponentInChildren(true) since it also searches the game object and its children. I am not sure whether it returns the first found or the first active found.
myGameObject.SetActive(false);
AnyComponent ac = myGameObject.GetComponent();
AnyComponent acic = myGameObject.GetComponentInChildren(true);
even though the GO has a AnyComponent attached, ac is null, acic is not (seems to be a 5.3 feature though).
http://docs.unity3d.com/ScriptReference/Component.GetComponentInChildren.html
Finally, for a component to expose the tick, it needs to have a Start method in the script (don't ask why...).
Setting .enabled turns one component on a GameObject on or off, e.g. an Image. Using SetActive() turns the whole GameObject on or off.
Choosing which to use should correspond with what you want to disable.