- 6
- 41 776
FumetsuHito
Приєднався 18 лип 2020
Unity - Read and Write To Twitch Chat Complete Guide
A complete guide on how to implement a Twitch chat reader and writer. This is the same implementation I used in my released game on steam "The Chatters Show"
Link to scripts shown in the guide: gist.github.com/FumetsuHito/ad38ffe0979128bae6cb71541f2f874f
00:00 Intro
01:45 Connecting To Twitch
07:24 Join a Channel
08:15 Possible Error
08:24 Joining a Channel
09:30 Async Runs After Play Mode
09:45 Send Message to Channel
10:47 Replying to Twitch Ping
11:10 String Format
12:22 Logs Approach to Reading Messages
16:14 Clearing the Logs
17:56 Comparing Channel Name
18:33 Limit on Writing to Twitch
Link to scripts shown in the guide: gist.github.com/FumetsuHito/ad38ffe0979128bae6cb71541f2f874f
00:00 Intro
01:45 Connecting To Twitch
07:24 Join a Channel
08:15 Possible Error
08:24 Joining a Channel
09:30 Async Runs After Play Mode
09:45 Send Message to Channel
10:47 Replying to Twitch Ping
11:10 String Format
12:22 Logs Approach to Reading Messages
16:14 Clearing the Logs
17:56 Comparing Channel Name
18:33 Limit on Writing to Twitch
Переглядів: 2 392
Відео
Unity - A Simple Ghost Replay System
Переглядів 7 тис.3 роки тому
Learn how to create a ghost replay system similar to racing games such as TrackMania. Scriptable Object Talk: ua-cam.com/video/raQ3iHhE_Kk/v-deo.html Time Stamp 00:00 Intro 00:23 What is a Ghost Replay 01:24 Ghost Holder Script 02:59 Ghost Recorder Script 03:57 Ghost Player Script 04:11 Why we Need Interpolation 04:55 Back to Ghost Player 05:47 End Result 06:10 How to have Multiple Ghosts
Unity in 60 Seconds - Remove Fog/Darkness When Scaling Objects
Переглядів 3,3 тис.3 роки тому
By the time you read this, this video should be almost over :D
Unity - Make Objects Between Camera and Player Transparent (No Shader Manipulation)
Переглядів 15 тис.3 роки тому
Learn how to make a simple yet powerful system to make objects that block your view transparent. 00:00 Introduction 01:11 Why Use This Over Shader Manipulation 02:20 Point to Note 03:51 Actual Code 09:34 Showcasing the system handling multiple objects
Unity - A Complete Scriptable Objects Events System (Including Passing Arguments)
Переглядів 14 тис.3 роки тому
A thorough tutorial on how to create and implement a scriptable objects based events system. Based on Ryan Hipple talk in 2017, but in this video I showcase my own solution to handle the passing of arguments, which was not touched in Ryan's talk. Ryan's Talk: ua-cam.com/video/raQ3iHhE_Kk/v-deo.html 00:00 Intro 00:53 Tutorial scene/game 02:22 Scriptable Objects Events System (2 component system)...
Unity vs Unreal Engine Cost - Which is Cheaper?
Переглядів 6584 роки тому
This is my very first video ever. Appreciate any feedback or comment to improve in the future. 00:00 Intro 02:05 Unity Cost 03:56 Unreal Engine Cost 06:25 Unity vs Unreal Engine Cost 07:51 Conclusion #Unity#UnrealEngine#GameEngineCost
Maybe you get that error because the connection is still established. Try maybe adding something like tcpClient.GetStream().Close(); tcpClient.Close(); when the app stops running
thank you so much this saved me, i looked at a dif totarial and the instant i heard him say "-2 divided by the pixel distance" i left, thanks for helping.
thanks!
Just what I needed, no other source explained where it was.
Any suggestions to stop read after editor stops?
Thank you.
Thank you for this. I literally only liking & commenting on this video because you showed the end result in the first 30 seconds. Too many other videos these days have a five minute speech before you figure out they aren't showing what you are looking for.
Sorry to say this, but this system is not scalable at all! Still, this gave me right away the idea I neede to solve the issue I was having in my game. Thanks man!
how can avoid duplicated events? I mean I follow almost the same steps, but I am seeing duplicated events, do I need to create different events to do the same? I go to my Data folder , and create an event using the scriptable object "GameEvent" which I can create a template for that event, similar to the base tempalte that Ryan Hipple does.... but the problem is I got a problem like you showed in "issue passing NO arguments"... however I pass the 2 arguments and I continue seeing the same change in all of my prefab... like if they using polymorphism, and I am not using polymorphism. the behaviour of bad practice, in my case, is having the same behaviour for duplicated prefabs. also the "hub classes"? are monobehaviours? but they are not still attached to any object? .
This solution is creative, but... but... I have trouble understanding the difference between dragging-dropping events and creating hard references through the code. They are the same thing, almost. When we do this we artificially create hard references anyway, they are just not visible, like sweeping the dust under the rug. Also if we are going to use a centralized static class, we can just create a huge, single static class that is going to be called anyways by any event raiser, and will be listened by all the listeners, and use it as a middleman. The ease of this video solution is to manage the event relationships through the editor, but in reality the cases are more complex. You have to create all these soft dependencies during runtime, and someone needs to manage this. Who will drag and drop the new connection during runtime? If you are worried about megalithic classes, and finding your code inside a huge static event manager, just make it a partial class and separate them into different sheets, label them with comments, or use inheritence or interface to differentiate between them, or just separate the events based on their functionality, like UIEvents, DataEvents, CollisionEvents etc. Which you already do here. Don't get me wrong. I don't have the answer and in fact I'm still searching for it. And this video showed me a new way, a clever way indeed, to change global variables when the event is raised and to read them when responding, because they happen sequentially anyways. And I will think about this, but just can't cope with editor drag&drop connections.
Thank you for sharing your experience and happy that this showed you a new method. to me the drag and drop is slightly more organizable and in front of you inshallah we will find the best answer
@@fumetsuhito5561 What do you think about the whole ECS system, do you have any experience with it? Does it solve some of these problems?
@@windwalkerrangerdm to be honest never used and I do not much background
Is there any way to Start the Ghost Replay on Button Press?
Definitely it is possible, for example you can make it so when the button is pressed the "Is reply" becomes true, then you substract the "timeValue" by the timevalue when the button was pressed
This helped me so much thank you
you are welcome
showing the end result AND explaining the logic!? You are a true hero.
Thank you
I love this so much
Thank you
I saw that you had a long comment that you deleted. I believe you were trying to solve a problem you had. But the comment is deleted now. did you manage to solve the problem?
@@fumetsuhito5561 yes, I have. I couldn't figure out how to implement this system with responses that are dependent on Update() or FixedUpdate(). Essentially, I was trying to move a door when a platform was stepped on. I realized I could do this by making the response something that changes a bool condition (which then triggers the door to move), or use a tweening library. I decided to go with LeanTween because it looks super clean and achieves the desired effect independently from Update(), so that way I can set one method as the response to the event. LeanTween also has a ton of different acceleration/deceleration curves.
@@dankodev happy to hear that
5:26 line 54 : transform.eulerangles = ghost. Position[index] ? why not ghost.rotation
i changed ghost.position to rotation and it work perfect
You correct it should it is better to be ghost.rotation
Thank you
you are welcome
Good very good
Thank you
Thank you so much :)
you are welcome
What would make this even better, is if you could fade the objects in/out instead of it instantly becoming transparent.
Exactly what I was looking for. Thank you very much for the cost breakdown.
This solutuion does work, but its extremely inefficent in real applications.
this is interesting but in my opinion it will drop a lot of performance when dealing with forests and many objects at the same time.
Best way I think is using stencils
Thank You So Much! Straight to the point and easy to follow.
Very simple to understand and works like a charm!! thanks for this tutorial!!
This is interesting, but isn't this a big performance hit with doubling the colliders? Especially if you are using mesh colliders.
Greetings Yes definitely, if we double the number of colliders it will affect the performance. But in this case we are not doubling the number of colliders, if we look back at 02:30 you will notice that the "SolidBody" and "TransBody" do not have a collider, only the parent object "GreenBlock" has the collider. The solid and transparent bodies only have rendering component (only visuals no physics) This is why I highlighted the point to make the rendering logic separate from other game logic such as collision physics
@@fumetsuhito5561 Oh so sorry, I missed that, I sort of wish I didn't get so far in my project with my assets. I'd take this approach, but I am using URP so maybe it'll be easier to do it with Shader than Standard... looking forward to that =/.
@@dibaterman As long as method suits your needs Shader or standard work Good luck on your project
@@fumetsuhito5561 Thanks man, you are appreciated.
thanks soooooo much u earnt a sub
tuyệt vời!!!!!!!!!!!!!!!!!!!!!!!
Thanks for the tutorial! But where is the documentation for connecting IRC in C#? I can only find some basic Information on the Twitch API site, but nothing detailed. Where did you have your information from? Thanks a lot!
Greetings, To be honest I only used 2 source to do all of this. The first is the one you mentioned on Twitch API site (and I agree it is basic) The second source is here medium.com/swlh/writing-a-twitch-bot-from-scratch-in-c-f59d9fed10f3 The second source is the guide I based my video on. Note that the "logs Approach to read Message" section of the video is something I came up with from experience.
THANK YOU!!!
You are welcome
Thanks man!
Great video, but Whenever I load my scene using the scene manager the ghost isn't there. Do you know how to fix this?
Thank you for the comment Without seeing your code it might be hard to figure the actual problem. if you want you can share the scripts you have and I can have a quick look Also just to understand if enter play mode when the scene is already selected it works, but if you enter play mode then load the scene it does not work?
dont know why but the ghost only appear in the last position recorded... not going throgh all positions
Greetings, Interesting, below are some points you can confirm 1-Confirm if the time stamps are recorded correctly in the ghost holder 2-Confrim if the timer ("timeValue" variable in the ghost player script) starts at 0 when you start the replay/scene and that it increments correctly 3-Confrim that the "GetIndex" method in the ghost player script (video time 5:05) is returning the expected index at each "timeValue" it might be that the "if" condition is slightly different or it is not looping correctly for some reason Hope this helps. If this does not work, you are welcome to share the script/code with me. Maybe I can help
Hmm, the messages i send from unity do not display til you refresh the streamchat
Hmm, to be honest I never encountered this problem. Sorry I do not think I can be of help here
I've got the same problem
Same :(
What about if you have 10.000 of those objects that you need to hide like trees for example and you create for mobile. This loops running each frame would not be too performance friendly. I like the idea with objects and having control to how transparent one looks.
Greetings Thank you for raising the point, and I will be honest I am not really experienced when it comes to optimization and how it will affect performance in such a game. But the loop only loops through the objects between the camera and the player (or reference you chose) I hard that a game would have 10,000 independent objects between the camera and the player.
You are actually right I have already 300 walls and 255 cubes so for this method you need to replace everything and that's kinda a mess. This is actually an example for this method but it's absolutely have a bad impact into your performance since you update every frame for each and for loops saying that I would not suggest to use this method at all. But sometimes it's actually good to learn something more
Incredible. Super clean and easy to understand! Thanks a lot for the help!
Much appreciated for the kind comment
i did all what you said and i dont know why the replay object is taking the positions correctly but after the record, in play it only spawns in the last position it was, non going throw all the positions... why? also you are creating a dont destroy on load object in play, when did u do that??, no info about the ghost object
Greetings, For you first question, since you are recording all the positions correctly I would confirm/look at the following points: 1-Confirm if the time stamps are recorded correctly in the ghost holder 2-Confrim if the timer ("timeValue" variable in the ghost player script) starts at 0 when you start the replay/scene and that it increments correctly 3-Confrim that the "GetIndex" method in the ghost player script (video time 5:05) is returning the expected index at each "timeValue" it might be that the "if" condition is slightly different or it is not looping correctly for some reason Hope this helps. If this does not work, you are welcome to share the script/code with me. Maybe I can help For the second question, to be honest I do not remember using the don't destroy on load method on anything. Maybe it was being created by default because of something I was not aware of. And functionally I do not think any part of the replay system needs a do not destroy on load method Also "no info about the ghost object", is this a question?
this is 0 performance friendly
designing with globals is … .. real bad design
How to do the same with YT Livestreams?
I do not know to be honest. not sure how youtube API works
@@fumetsuhito5561 Ohh! It's Okay. Thanks for the reply.
wow dude this is solid. always wondered how ghosts work, can't wait to try it
Thank you for the comment Hope it works for your project
good job
Thank you. Hope you are doing and all is fine with you Alina
Nice tutor, however I don`t like arguments passing method for some reason. And why are subtitles not available?
Thanks for the nice comment. I do not have subtitles
This is an awesome tutorial, thanks. I would love to learn how to save/load this data from an external file as I'm trying to set up a system where people can watch other people's replays. I tried using the binary formatter but it doesn't play nice with the list variables. Do you have any idea how I could go about a replay save/load system?
Thanks for the kind words. For saving and loading system one recommendation I have is saving in JSON using JSONutility. Here is a link to a good guide which I used myself ua-cam.com/video/uD7y4T4PVk0/v-deo.html JSON format is compatible with many interfaces which makes it good. The only set back I see for this method is that the save file is easily modifiable as it is written in human readable format. But at the same time this is powerful as you can easily change setting save data by just changing the text file.
@@fumetsuhito5561 hey thanks for the reference! i was having some issues but I fixed them all :) thanks again for the video
dude im watching at 0.25 and still cant see what you do in your editor, go easy on the speed up pls that's so hard to follow
Can i take these codes?
of course
This is so helpful for my school project, thanks!!!!
Thank you so much for keeping it short and to the point. There could sometimes be some glitches that can be avoided by using quaternion as follow; using UnityEngine; public class GhostRecorder : MonoBehaviour { public Ghost ghost; private float timer; private float timeValue; private void Awake() { if (ghost.isRecord) { ghost.ResetData(); timeValue = 0; timer = 0; } } void Update() { timer += Time.unscaledDeltaTime; timeValue += Time.unscaledDeltaTime; if (ghost.isRecord & timer >= 1 / ghost.recordFrequency) { ghost.timeStamp.Add(timeValue); ghost.position.Add(this.transform.position); ghost.rotation.Add(this.transform.rotation); timer = 0; } } } and ... using System.Collections; using System.Collections.Generic; using UnityEngine; public class GhostPlayer : MonoBehaviour { public Ghost ghost; private float timeValue; private int index1; private int index2; private void Awake() { timeValue = 0; } void Update() { timeValue += Time.unscaledDeltaTime; if (ghost.isReplay) { GetIndex(); SetTransform(); } } private void GetIndex() { for (int i = 0; i < ghost.timeStamp.Count - 2; i++) { if (ghost.timeStamp[i] == timeValue) { index1 = i; index2 = i; return; } else if (ghost.timeStamp[i] < timeValue & timeValue < ghost.timeStamp[i + 1]) { index1 = i; index2 = i + 1; return; } } index1 = ghost.timeStamp.Count - 1; index2 = ghost.timeStamp.Count - 1; } private void SetTransform() { if (index1 == index2) { this.transform.position = ghost.position[index1]; this.transform.rotation = ghost.rotation[index1]; } else { float interpolationFactor = (timeValue - ghost.timeStamp[index1]) / (ghost.timeStamp[index2] - ghost.timeStamp[index1]); this.transform.position = Vector3.Lerp(ghost.position[index1], ghost.position[index2], interpolationFactor); this.transform.rotation = Quaternion.Slerp(ghost.rotation[index1], ghost.rotation[index2], interpolationFactor); } } }
great tutorial!! wish i found your channel earlier! liked and subscribed :)
This is awesome, great tutorial, straight to the point, easy to follow and to understand, good job! Wish that more tutorials on YT would be like that.
Excellent tutorial, thanks for sharing. I noticed that the ghost gets stuck in the rotation when the Euler exceeds 180 degrees and the object is shaking at times, to fix that I applied the WrapAngle on the euler angle to fix that, it was perfect. Here's the WrapAngle function code for those who want to use it: private static float WrapAngle(float angle) { angle %= 360; if (angle > 180) return angle - 360; return angle; } to implement in the code looks like this: float rotX = WrapAngle(ghost.rotation[index1].x); float rotY = WrapAngle(ghost.rotation[index1].y); float rotZ = WrapAngle(ghost.rotation[index1].z); Vector3 rotFinal = new Vector3(rotX, rotY, rotZ); float rotX2 = WrapAngle(ghost.rotation[index2].x); float rotY2 = WrapAngle(ghost.rotation[index2].y); float rotZ2 = WrapAngle(ghost.rotation[index2].z); Vector3 rotFinal2 = new Vector3(rotX2, rotY2, rotZ2); if (index1 == index2) { this.transform.position = ghost.position[index1]; this.transform.eulerAngles = rotFinal; } else { float interpolationFactor = (timeValue - ghost.timeStamp[index1]) / (ghost.timeStamp[index2] - ghost.timeStamp[index1]); this.transform.position = Vector3.Lerp(ghost.position[index1], ghost.position[index2], interpolationFactor); this.transform.eulerAngles = Vector3.Lerp(rotFinal, rotFinal2, interpolationFactor); }
Much appreciated for the comment. Also thank you for sharing your findings, it can definitely help other people. Note there is another users who faces a similar problem and his solution was to use Quaternion list instead of Vector3. the user is Asjagadra and his comment is below somewhere
I tried your modification and I got some glitches. So as others commented I went for the Quaternion and it workd!