2020-08-21 10:38:53

Jeu Pixel Art Contrôlable dans un tchat Twitch


2D Pixel Art Game Connect to Twitch



Bonjour, bonsoir, j'espère que vous allez bien, moi personnellement je vais bien, dirait pas mais depuis le dernier post sur Unity, en vrai j'ai fait énormément de truc que je n'ai pas encore eux le temps de poster, mais ça arrivera petit à petit.

Aujourd'hui je me suis amusé a créé un jeu qui est relié à votre compte twitch, mais dites-moi à quoi ça va-t-il servir ?

La question est rapide, pour pouvoir jouer avec les viewers en stream, pour pimenter les choses dans la partie.

ça m’a pris énormément de temps à travailler dessus (même si en une journée j'ai déjà fait une version jouable).

Je me suis beaucoup casser la tête, mais je trouve que le plus dur était de trouver un bon asset pack pour les graphismes puisque je ne suis pas fort dans les graphismes, ma spécialité c'est plutôt la programmation.

venons rapide au sujet, donc comme j'ai dit les viewers peuvent jouer avec le streameur, mais comment ?

Les viewers peuvent utiliser des commandes comme : Left, Right, Up, Attack, Block, Roll.

Grâce à ces commandes que vous pouvez taper dans le tchat twitch vous pouvez contrôler les personnages dans le jeu ou le streameur et actuellement entrain de jouer, aidez l'ou pimenté ça partie pour le faire rager, t'elle est votre choix.

Exemple dans mes débuts du jeux il étais comme ceci :

89-c409dfddd260d7fb7c08c5ae2b52adc6.gif



Mais j'ai décidé d'aller beaucoup plus loin, donc je me suis permis de faire réglé tous les problèmes, ça a duré plus de 4h pour réglé tout ça.

Version actuelle :

90-6ca69c7d7b272768f376b435c66f94bd.gif



Une bonne grosse amélioration et des bug corriger.

Comme dans mon habitude je vais vous donner les codes sources de mes codes avec justement des commentaires en anglais.

TwitchTchat :

using System.Collections;using System.Collections.Generic;
using UnityEngine;
using System;
using System.ComponentModel;
using System.Net.Sockets;
using System.IO;
using UnityEngine.UI;

public class TwitchChat : MonoBehaviour {

private TcpClient twitchClient;
private StreamReader reader;
private StreamWriter writer;

public string username, password, channelName; //Get the password from https://twitchapps.com/tmi

public Text chatBox;
public Rigidbody2D player;
public int speed;

public HeroKnight heroKnight;

void Start () {
Connect();
}

void Update () {
if (!twitchClient.Connected)
{
Connect();
}

ReadChat();

}

private void Connect()
{
twitchClient = new TcpClient("irc.chat.twitch.tv", 6667);
reader = new StreamReader(twitchClient.GetStream());
writer = new StreamWriter(twitchClient.GetStream());

writer.WriteLine("PASS " + password);
writer.WriteLine("NICK " + username);
writer.WriteLine("USER " + username + " 8 * :" + username);
writer.WriteLine("JOIN #" + channelName);
writer.Flush();
}

private void ReadChat()
{
if(twitchClient.Available > 0)
{
var message = reader.ReadLine(); //Read in the current message

if (message.Contains("PRIVMSG"))
{
//Get the users name by splitting it from the string
var splitPoint = message.IndexOf("!", 1);
var chatName = message.Substring(0, splitPoint);
chatName = chatName.Substring(1);

//Get the users message by splitting it from the string
splitPoint = message.IndexOf(":", 1);
message = message.Substring(splitPoint + 1);
//print(String.Format("{0}: {1}", chatName, message));
chatBox.text = chatBox.text + "\n" + String.Format("{0}: {1}", chatName, message);

//Run the instructions to control the game!
GameInputs(message);
}
}
}

private void GameInputs(string ChatInputs)
{
if(ChatInputs.ToLower() == "left")
{
player.AddForce(Vector2.left * (speed * 2200));
heroKnight.GetComponent().flipX = true;
heroKnight.m_delayToIdle = 0.05f;
heroKnight.m_animator.SetInteger("AnimState", 1);
heroKnight.m_facingDirection = -1;
heroKnight.m_ColissionL.SetActive(true);
heroKnight.m_ColissionR.SetActive(false);
}

if(ChatInputs.ToLower() == "right")
{
player.AddForce(Vector2.right * (speed * 2200));
heroKnight.GetComponent().flipX = false;
heroKnight.m_delayToIdle = 0.05f;
heroKnight.m_animator.SetInteger("AnimState", 1);
heroKnight.m_facingDirection = 1;
heroKnight.m_ColissionL.SetActive(false);
heroKnight.m_ColissionR.SetActive(true);
}

if(ChatInputs.ToLower() == "up" && heroKnight.m_grounded == true)
{
player.AddForce(Vector2.up * (speed * 150));
heroKnight.m_animator.SetTrigger("Jump");
heroKnight.m_grounded = false;
heroKnight.m_animator.SetBool("Grounded", heroKnight.m_grounded);
heroKnight.m_body2d.velocity = new Vector2(heroKnight.m_body2d.velocity.x, heroKnight.m_jumpForce);
heroKnight.m_groundSensor.Disable(0.2f);
}

if(ChatInputs.ToLower() == "attack")
{
heroKnight.m_currentAttack++;

if (heroKnight.m_currentAttack > 3)
heroKnight.m_currentAttack = 1;

if (heroKnight.m_timeSinceAttack > 1.0f)
heroKnight.m_currentAttack = 1;

heroKnight.m_animator.SetTrigger("Attack" + heroKnight.m_currentAttack);

heroKnight.m_timeSinceAttack = 0.0f;

if (heroKnight.m_facingDirection == 1)
{
heroKnight.m_ColissionL.SetActive(false);
heroKnight.m_ColissionR.SetActive(true);
}
if (heroKnight.m_facingDirection == -1)
{
heroKnight.m_ColissionL.SetActive(true);
heroKnight.m_ColissionR.SetActive(false);
}
}

if(ChatInputs.ToLower() == "block")
{
if(heroKnight.m_facingDirection == -1)
{
heroKnight.m_ColissionRBlock.SetActive(false);
heroKnight.m_ColissionLBlock.SetActive(true);
if(heroKnight.resetBlocktwitch = true || heroKnight.m_currentAttack == 2)
{
heroKnight.m_ColissionLBlock.SetActive(false);
heroKnight.m_ColissionRBlock.SetActive(false);
}
}
else
{
heroKnight.m_ColissionLBlock.SetActive(false);
heroKnight.m_ColissionRBlock.SetActive(true);
if(heroKnight.resetBlocktwitch = true || heroKnight.m_currentAttack == 2)
{
heroKnight.m_ColissionRBlock.SetActive(false);
heroKnight.m_ColissionLBlock.SetActive(false);
}
}
heroKnight.m_animator.SetTrigger("Block");
heroKnight.m_animator.SetBool("IdleBlock", true);
heroKnight.m_animator.SetBool("IdleBlock", false);
}

if(ChatInputs.ToLower() == "roll" && !heroKnight.m_rolling)
{
heroKnight.m_rolling = true;
heroKnight.m_animator.SetTrigger("Roll");
heroKnight.m_body2d.velocity = new Vector2(heroKnight.m_facingDirection * heroKnight.m_rollForce, heroKnight.m_body2d.velocity.y);
}
}
}



HeroKnight :

using UnityEngine;using System.Collections;

public class HeroKnight : MonoBehaviour {

[SerializeField] public float m_speed = 4.0f;
[SerializeField] public float m_jumpForce = 7.5f;
[SerializeField] public float m_rollForce = 6.0f;
[SerializeField] public bool m_noBlood = false;
[SerializeField] public GameObject m_slideDust;

public Animator m_animator;
public Rigidbody2D m_body2d;
public Sensor_HeroKnight m_groundSensor;
public Sensor_HeroKnight m_wallSensorR1;
public Sensor_HeroKnight m_wallSensorR2;
public Sensor_HeroKnight m_wallSensorL1;
public Sensor_HeroKnight m_wallSensorL2;
public bool m_grounded = false;
public bool m_rolling = false;
public int m_facingDirection = 1;
public int m_currentAttack = 0;
public float m_timeSinceAttack = 0.0f;
public float m_delayToIdle = 0.0f;
public GameObject m_ColissionR;
public GameObject m_ColissionL;
public GameObject m_ColissionRBlock;
public GameObject m_ColissionLBlock;

public float resetBlocking = 0.0f;
public float blockisReset = 2.5f;
public bool resetBlocktwitch = false;
public float timerAttack = 0.0f;
public float resetTimerAttack = 1.0f;
public int disableAttackColission = 0;
public float countdownAttack = 0.8f;

public bool m_canJump = true;


// Use this for initialization
void Start ()
{
m_animator = GetComponent();
m_body2d = GetComponent();
m_groundSensor = transform.Find("GroundSensor").GetComponent();
m_wallSensorR1 = transform.Find("WallSensor_R1").GetComponent();
m_wallSensorR2 = transform.Find("WallSensor_R2").GetComponent();
m_wallSensorL1 = transform.Find("WallSensor_L1").GetComponent();
m_wallSensorL2 = transform.Find("WallSensor_L2").GetComponent();
}

// Update is called once per frame
void Update()
{

resetBlocking += Time.deltaTime;
timerAttack += Time.deltaTime;

if(resetBlocking >= 1.0f)
{
resetBlocktwitch = true;
}

if (timerAttack >= resetTimerAttack)
{
timerAttack = 0.0f;
disableAttackColission = 1;
m_ColissionL.SetActive(false);
m_ColissionR.SetActive(false);
}

if (resetBlocking >= blockisReset)
{
resetBlocking = 0.0f;
resetBlocktwitch = false;
}

// Increase timer that controls attack combo
m_timeSinceAttack += Time.deltaTime;

//Check if character just landed on the ground
if (!m_grounded && m_groundSensor.State())
{
m_grounded = true;
m_animator.SetBool("Grounded", m_grounded);
m_canJump = true;
}

//Check if character just started falling
if (m_grounded && !m_groundSensor.State())
{
m_grounded = false;
m_animator.SetBool("Grounded", m_grounded);
m_canJump = false;
}

// -- Handle input and movement --
float inputX = Input.GetAxis("Horizontal");

// Swap direction of sprite depending on walk direction
if (inputX > 0)
{
GetComponent().flipX = false;
m_facingDirection = 1;
}

else if (inputX < 0)
{
GetComponent().flipX = true;
m_facingDirection = -1;
}

// Move
if (!m_rolling)
m_body2d.velocity = new Vector2(inputX * m_speed, m_body2d.velocity.y);

//Set AirSpeed in animator
m_animator.SetFloat("AirSpeedY", m_body2d.velocity.y);

// -- Handle Animations --
//Wall Slide
m_animator.SetBool("WallSlide", (m_wallSensorR1.State() && m_wallSensorR2.State()) || (m_wallSensorL1.State() && m_wallSensorL2.State()));

//Death
if (Input.GetKeyDown("e"))
{
m_animator.SetBool("noBlood", m_noBlood);
m_animator.SetTrigger("Death");
}

//Hurt
else if (Input.GetKeyDown("q"))
m_animator.SetTrigger("Hurt");

//Attack
else if (Input.GetMouseButtonDown(0) && m_timeSinceAttack > 0.25f)
{
m_currentAttack++;

// Loop back to one after third attack
if (m_currentAttack > 3)
{
m_currentAttack = 1;
m_ColissionL.SetActive(false);
m_ColissionR.SetActive(false);
}
// Reset Attack combo if time since last attack is too large
if (m_timeSinceAttack > 1.0f)
{
m_currentAttack = 1;
m_ColissionL.SetActive(false);
m_ColissionR.SetActive(false);
}

if (m_facingDirection == 1)
{
m_ColissionL.SetActive(false);
m_ColissionR.SetActive(true);
}
if(m_facingDirection == -1)
{
m_ColissionL.SetActive(true);
m_ColissionR.SetActive(false);
}

// Call one of three attack animations "Attack1", "Attack2", "Attack3"
m_animator.SetTrigger("Attack" + m_currentAttack);

// Reset timer
m_timeSinceAttack = 0.0f;

/* if(disableAttackColission == 1)
{
m_ColissionL.SetActive(false);
m_ColissionR.SetActive(false);
disableAttackColission = 0;
} */

}

// Block
else if (Input.GetMouseButtonDown(1))
{
m_animator.SetTrigger("Block");
m_animator.SetBool("IdleBlock", true);
if(m_facingDirection == -1)
{
m_ColissionLBlock.SetActive(true);
}
else
{
m_ColissionRBlock.SetActive(true);
}
}

else if (Input.GetMouseButtonUp(1))
{
m_animator.SetBool("IdleBlock", false);
m_ColissionRBlock.SetActive(false);
m_ColissionLBlock.SetActive(false);
}

// Roll
else if (Input.GetKeyDown("left shift") && !m_rolling)
{
m_rolling = true;
m_animator.SetTrigger("Roll");
m_body2d.velocity = new Vector2(m_facingDirection * m_rollForce, m_body2d.velocity.y);
}


//Jump
else if (Input.GetKeyDown("w") && m_grounded == true && m_canJump == true)
{
m_animator.SetTrigger("Jump");
m_grounded = false;
m_animator.SetBool("Grounded", m_grounded);
m_body2d.velocity = new Vector2(m_body2d.velocity.x, m_jumpForce);
m_groundSensor.Disable(0.2f);
m_canJump = false;
}

//Run
else if (Mathf.Abs(inputX) > Mathf.Epsilon)
{
// Reset timer
m_delayToIdle = 0.05f;
m_animator.SetInteger("AnimState", 1);
}

//Idle
else
{
// Prevents flickering transitions to idle
m_delayToIdle -= Time.deltaTime;
if(m_delayToIdle < 0)
m_animator.SetInteger("AnimState", 0);
}
}

// Animation Events
// Called in end of roll animation.
void AE_ResetRoll()
{
m_rolling = false;
}

// Called in slide animation.
void AE_SlideDust()
{
Vector3 spawnPosition;

if (m_facingDirection == 1)
spawnPosition = m_wallSensorR2.transform.position;
else
spawnPosition = m_wallSensorL2.transform.position;

if (m_slideDust != null)
{
// Set correct arrow spawn position
GameObject dust = Instantiate(m_slideDust, spawnPosition, gameObject.transform.localRotation) as GameObject;
// Turn arrow in correct direction
dust.transform.localScale = new Vector3(m_facingDirection, 1, 1);
}
}
}


- Maxime664100 Like

Retour


Commentaires






Bootstrap