Introduction and Session Goals
확인 완료한 버전: 2017.1
-
난이도: 초급
In this session we will learn how to create an in-game video player which the player can interact with using first person shooter controls. The goals of this session are to learn how to use the VideoPlayer component and how to write scripts to control it. In this session we will introduce the session and what we will learn.


Introduction and Session Goals
초급 Graphics
Download the assets to follow along with this training here
WorldSpaceVideo
Code snippet
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Video;
using UnityEngine.UI;
public class WorldSpaceVideo : MonoBehaviour {
public Material playButtonMaterial;
public Material pauseButtonMaterial;
public Renderer playButtonRenderer;
public VideoClip[] videoClips;
public Text currentMinutes;
public Text currentSeconds;
public Text totalMinutes;
public Text totalSeconds;
public PlayHeadMover playHeadMover;
private VideoPlayer videoPlayer;
private int videoClipIndex;
void Awake()
{
videoPlayer = GetComponent<VideoPlayer> ();
}
// Use this for initialization
void Start ()
{
videoPlayer.targetTexture.Release ();
videoPlayer.clip = videoClips [0];
}
// Update is called once per frame
void Update ()
{
if (videoPlayer.isPlaying)
{
SetCurrentTimeUI ();
playHeadMover.MovePlayhead (CalculatePlayedFraction ());
}
}
public void SetNextClip()
{
videoClipIndex++;
if (videoClipIndex >= videoClips.Length)
{
videoClipIndex = videoClipIndex % videoClips.Length;
}
videoPlayer.clip = videoClips [videoClipIndex];
SetTotalTimeUI ();
videoPlayer.Play ();
}
public void PlayPause()
{
if (videoPlayer.isPlaying)
{
videoPlayer.Pause ();
playButtonRenderer.material = playButtonMaterial;
} else
{
videoPlayer.Play ();
SetTotalTimeUI ();
playButtonRenderer.material = pauseButtonMaterial;
}
}
void SetCurrentTimeUI()
{
string minutes = Mathf.Floor ((int)videoPlayer.time / 60).ToString ("00");
string seconds = ((int)videoPlayer.time % 60).ToString ("00");
currentMinutes.text = minutes;
currentSeconds.text = seconds;
}
void SetTotalTimeUI()
{
string minutes = Mathf.Floor ((int)videoPlayer.clip.length / 60).ToString ("00");
string seconds = ((int)videoPlayer.clip.length % 60).ToString ("00");
totalMinutes.text = minutes;
totalSeconds.text = seconds;
}
double CalculatePlayedFraction()
{
double fraction = (double)videoPlayer.frame / (double)videoPlayer.clip.frameCount;
return fraction;
}
}
ShootableUI
Code snippet
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public abstract class ShootableUI : MonoBehaviour
{
public WorldSpaceVideo worldSpaceVideo;
public abstract void ShotClick();
}
PlaybuttonControl
Code snippet
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlaybuttonControl : ShootableUI
{
public override void ShotClick ()
{
worldSpaceVideo.PlayPause ();
}
}
RaycastShootComplete
Code snippet
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
public class RayCastShootComplete : MonoBehaviour {
public int gunDamage = 1; // Set the number of hitpoints that this gun will take away from shot objects with a health script
public float fireRate = 0.25f; // Number in seconds which controls how often the player can fire
public float weaponRange = 50f; // Distance in Unity units over which the player can fire
public float hitForce = 100f; // Amount of force which will be added to objects with a rigidbody shot by the player
public Transform gunEnd; // Holds a reference to the gun end object, marking the muzzle location of the gun
private Camera fpsCam; // Holds a reference to the first person camera
private WaitForSeconds shotDuration = new WaitForSeconds(0.07f); // WaitForSeconds object used by our ShotEffect coroutine, determines time laser line will remain visible
private AudioSource gunAudio; // Reference to the audio source which will play our shooting sound effect
private LineRenderer laserLine; // Reference to the LineRenderer component which will display our laserline
private float nextFire; // Float to store the time the player will be allowed to fire again, after firing
void Start ()
{
// Get and store a reference to our LineRenderer component
laserLine = GetComponent<LineRenderer>();
// Get and store a reference to our AudioSource component
gunAudio = GetComponent<AudioSource>();
// Get and store a reference to our Camera by searching this GameObject and its parents
fpsCam = GetComponentInParent<Camera>();
}
void Update ()
{
// Check if the player has pressed the fire button and if enough time has elapsed since they last fired
if (Input.GetButtonDown("Fire1") && Time.time > nextFire)
{
// Update the time when our player can fire next
nextFire = Time.time + fireRate;
// Start our ShotEffect coroutine to turn our laser line on and off
StartCoroutine (ShotEffect());
// Create a vector at the center of our camera's viewport
Vector3 rayOrigin = fpsCam.ViewportToWorldPoint (new Vector3(0.5f, 0.5f, 0.0f));
// Declare a raycast hit to store information about what our raycast has hit
RaycastHit hit;
// Set the start position for our visual effect for our laser to the position of gunEnd
laserLine.SetPosition (0, gunEnd.position);
// Check if our raycast has hit anything
if (Physics.Raycast (rayOrigin, fpsCam.transform.forward, out hit, weaponRange))
{
// Set the end position for our laser line
laserLine.SetPosition (1, hit.point);
// Get a reference to a health script attached to the collider we hit
ShootableBox health = hit.collider.GetComponent<ShootableBox>();
// If there was a health script attached
if (health != null)
{
// Call the damage function of that script, passing in our gunDamage variable
health.Damage (gunDamage);
}
// Check if the object we hit has a rigidbody attached
if (hit.rigidbody != null)
{
// Add force to the rigidbody we hit, in the direction from which it was hit
hit.rigidbody.AddForce (-hit.normal * hitForce);
}
ShootableUI shotUI;
shotUI = hit.collider.GetComponent<ShootableUI> ();
if (shotUI != null)
{
shotUI.ShotClick ();
}
}
else
{
// If we did not hit anything, set the end of the line to a position directly in front of the camera at the distance of weaponRange
laserLine.SetPosition (1, rayOrigin + (fpsCam.transform.forward * weaponRange));
}
}
}
private IEnumerator ShotEffect()
{
// Play the shooting sound effect
gunAudio.Play ();
// Turn on our line renderer
laserLine.enabled = true;
//Wait for .07 seconds
yield return shotDuration;
// Deactivate our line renderer after waiting
laserLine.enabled = false;
}
}
NextButtonControl
Code snippet
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NextButtonControl : ShootableUI {
public override void ShotClick ()
{
worldSpaceVideo.SetNextClip ();
}
}
PlayHeadMover
Code snippet
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayHeadMover : MonoBehaviour
{
public Transform startPoint;
public Transform endPoint;
public void MovePlayhead(double playedFraction)
{
transform.position = Vector3.Lerp (startPoint.position, endPoint.position, (float)playedFraction);
}
}