Wikipedia:Reference desk/Archives/Computing/2017 April 22

From Wikipedia, the free encyclopedia
Computing desk
< April 21 << Mar | April | May >> April 23 >
Welcome to the Wikipedia Computing Reference Desk Archives
The page you are currently viewing is an archive page. While you can leave answers for any questions shown below, please ask new questions on one of the current reference desk pages.


April 22[edit]

need help with assignment in Unity/C#[edit]

My daughter is having a problem with an assignment in Unity/C#. This is a two-player game. The arrow keys control the first player and the W-A-S-F keys control the second player. She had this working but she added to the program and the W-A-S-F keys quit working for the second player. I think it must be something simple, but I don't know this language. Can someone help a little?

Unity/C# code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class PlayerController : MonoBehaviour {

    private Rigidbody rb;
    public float speed;
    public Text winLose;
    public Text winLoseTwo;
    Vector3 startPosition;
    float moveHorizontal = 0f;
    float moveVertical = 0f;
    public AudioClip enemyHit;
    public AudioClip collect;
    public AudioClip hole;
    public AudioClip checkpoint;
    private AudioSource source;
    private AudioSource hit;
    public float hitVol;
    public int playerOneScore;
    public int playerTwoScore;
    public Text pOS;
    //pOS will display playerOneScore
    public Text pTS;
    //pTS will display playerTwoScore


    void Start()
    {
        rb = GetComponent<Rigidbody>();
        winLose.text = "";
        playerOneScore = 0;
        playerTwoScore = 0;
        pOS.text = "Player-1's score:" + playerOneScore;
        pTS.text = "Player-2's score:" + playerTwoScore;

        //this stores the starting position so the players can be sent back if they hit a hole or enemy
        startPosition = transform.position;
    }

    // Update is called once per frame this currently does nothing
    void Update () {   
        
            }

    void FixedUpdate()
    {
        // the following two lines gets directional input from the keyboard
        if (this.gameObject.CompareTag("Player1"))
        {
        moveHorizontal = Input.GetAxis("Horizontal");
        moveVertical = Input.GetAxis("Vertical");
    }
        else
        {
           moveHorizontal = Input.GetAxis("Horizontal2");
           moveVertical = Input.GetAxis("Vertical2");
        }

        //this line stores the two lines of input into a single variable called movement
        Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);

        pOS.text = "Player-1's score:" + playerOneScore;
        pTS.text = "Player-2's score:" + playerTwoScore;

        //the following conditional tells the player to move during the game
        // this is use to prevent people from moving after the game is done 
        // so the player will only move if they have not lost
  
              if (winLose.text != "You Lose!! :(")
        {
            rb.AddForce(movement * speed);
            //speed is set in unity so user can decide fast the player can move
        }
        

    }

        void Awake()
    {

        source = GetComponent<AudioSource>();

    }

    void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.CompareTag("Sphere"))
        {
// when player touches the golden sphere which is the goal
            other.gameObject.SetActive(false);
            if (this.gameObject.CompareTag("Player1")){
                winLose.text = "You Win!!!"; }
            else { winLoseTwo.text = "You Win!!!"; }
            // this tell player that they have won
        }
        
        if (other.gameObject.CompareTag("Enemy"))
        {
            //when player collides with enemy (the red guys)
            //other.gameObject.SetActive(false);
            
            source.PlayOneShot(enemyHit, hitVol);
            //plays a sound when a player collides with an enemy

            //transform.position = startPosition;


            if (this.gameObject.CompareTag("Player1"))
                {
                playerOneScore -= 15;
            }
            else { 
                playerTwoScore -= 15; }
             //players lose 15 points upon touching enemy
        }
        
        if (other.gameObject.CompareTag("Hole"))
        {
            transform.position = startPosition;
                //resets the ball position if player touches a hole
                //i.e. sends player to start or checkpoint
        }

        if (other.gameObject.CompareTag("Checkpoint"))
        {
            startPosition = transform.position;
            //this lets the player be sent to the last checkpoint they touched instead of start if they hit a hole
            
            source.PlayOneShot(checkpoint, hitVol);
            
            if (this.gameObject.CompareTag("Player1"))
            {
                playerOneScore += 10;
            }
            else 
            { playerTwoScore += 10; }
        }

        //the following if statements tells a player of they win or lose based on whether or not the other player wins or lose
        if (winLose.text == "You Win!!!")
        {
            winLoseTwo.text = "You Lose!! :(";
        }
        if (winLoseTwo.text == "You Win!!!")
        {
            winLose.text = "You Lose!! :(";
        }
        if (winLose.text == "You Lose!! :(")
        {
            winLoseTwo.text = "You Win!!!";
        }
        if (winLoseTwo.text == "You Lose!! :(")
        {
            winLose.text = "You Win!!!";
        }

Thank you. Bubba73 You talkin' to me? 02:24, 22 April 2017 (UTC)[reply]

Without looking at the code, I suggest she goes back to the previous working version of the code, then adds in as little as possible at a time, until it breaks again. This should help to isolate the problem. You could also list the previous, working version here, so we can do the same. StuRat (talk) 02:53, 22 April 2017 (UTC)[reply]
She sent me the code in a Word file, with the changes she had made highlighted. I've commented out those lines. Bubba73 You talkin' to me? 03:13, 22 April 2017 (UTC)[reply]
Changes since working version are commented out
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class PlayerController : MonoBehaviour {

    private Rigidbody rb;
    public float speed;
    public Text winLose;
    public Text winLoseTwo;
    Vector3 startPosition;
    float moveHorizontal = 0f;
    float moveVertical = 0f;
    public AudioClip enemyHit;
    public AudioClip collect;
    public AudioClip hole;
//    private AudioSource source;
    private AudioSource hit;
    public float hitVol;
//    public int playerOneScore;
//    public int playerTwoScore;
//    public Text pOS;
//    //pOS will display playerOneScore
//     public Text pTS;
//    //pTS will display playerTwoScore


    void Start()
    {
        rb = GetComponent<Rigidbody>();
        winLose.text = "";
  //      playerOneScore = 0;
  //      playerTwoScore = 0;
  //      pOS.text = "Player-1's score:" + playerOneScore;
  //      pTS.text = "Player-2's score:" + playerTwoScore;

        //this stores the starting position so the players can be sent back if they hit a hole or enemy
        startPosition = transform.position;
    }

    // Update is called once per frame this currently does nothing
    void Update () {   
        
            }

    void FixedUpdate()
    {
        // the following two lines gets directional input from the keyboard
        if (this.gameObject.CompareTag("Player1"))
        {
        moveHorizontal = Input.GetAxis("Horizontal");
        moveVertical = Input.GetAxis("Vertical");
    }
        else
        {
           moveHorizontal = Input.GetAxis("Horizontal2");
           moveVertical = Input.GetAxis("Vertical2");
        }

        //this line stores the two lines of input into a single variable called movement
        Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);

//        pOS.text = "Player-1's score:" + playerOneScore;
//        pTS.text = "Player-2's score:" + playerTwoScore;

        //the following conditional tells the player to move during the game
        // this is use to prevent people from moving after the game is done 
        // so the player will only move if they have not lost
  
              if (winLose.text != "You Lose!! :(")
        {
            rb.AddForce(movement * speed);
            //speed is set in unity so user can decide fast the player can move
        }
        

    }

        void Awake()
    {

        source = GetComponent<AudioSource>();

    }

    void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.CompareTag("Sphere"))
        {
// when player touches the golden sphere which is the goal
            other.gameObject.SetActive(false);
            if (this.gameObject.CompareTag("Player1")){
                winLose.text = "You Win!!!"; }
            else { winLoseTwo.text = "You Win!!!"; }
            // this tell player that they have won
        }
        
        if (other.gameObject.CompareTag("Enemy"))
        {
            //when player collides with enemy (the red guys)
            //other.gameObject.SetActive(false);
            
//            source.PlayOneShot(enemyHit, hitVol);
            //plays a sound when a player collides with an enemy

//            //transform.position = startPosition;


//          if (this.gameObject.CompareTag("Player1"))
//               {
//               playerOneScore -= 15;
//            }
//            else { 
//                playerTwoScore -= 15; }
//             //players lose 15 points upon touching enemy
        }
        
        if (other.gameObject.CompareTag("Hole"))
        {
            transform.position = startPosition;
                //resets the ball position if player touches a hole
                //i.e. sends player to start or checkpoint
        }

        if (other.gameObject.CompareTag("Checkpoint"))
        {
            startPosition = transform.position;
            //this lets the player be sent to the last checkpoint they touched instead of start if they hit a hole
            
//           source.PlayOneShot(checkpoint, hitVol);
            
//            if (this.gameObject.CompareTag("Player1"))
//            {
//                playerOneScore += 10;
//            }
//            else 
//            { playerTwoScore += 10; }
        }

        //the following if statements tells a player of they win or lose based on whether or not the other player wins or lose
        if (winLose.text == "You Win!!!")
        {
            winLoseTwo.text = "You Lose!! :(";
        }
        if (winLoseTwo.text == "You Win!!!")
        {
            winLose.text = "You Lose!! :(";
        }
        if (winLose.text == "You Lose!! :(")
        {
            winLoseTwo.text = "You Win!!!";
        }
        if (winLoseTwo.text == "You Lose!! :(")
        {
            winLose.text = "You Win!!!";
        }

Two obvious first things to check :

  • Make sure the player object is still tagged "Player1". That would be easy to accidentally change in the editor, and would cause this code to assume the player was player two. (And thus not affected by WASD.) Oh. I misread the question. I thought player 1 was the stuck one.
  • Make sure the script is actually running. Unity scripts can fail surprisingly gracefully with just an error in the log window. Perhaps there's a null reference somewhere and you're not noticing the error because you're staring at the character who stubbornly refuses to move.

ApLundell (talk) 03:29, 22 April 2017 (UTC)[reply]

It looks like "speed"(really acceleration) is set in the editor. Make sure it's been correctly set for both players.
There's also a bit of a logical oddity here. This script looks like it will be attached to each player individually, but it contains as member values both player's scores. At best this is redundant, at worst it could cause the scoring to be inconsistent. ApLundell (talk) 03:40, 22 April 2017 (UTC)[reply]
In her note to me, she says that the players share the script:
"Horizontal2 and Vertical2 are keyed to wasd (for Player2).
Changes are highlighted including. I commented out a line from the original code so I highlighted just the slashes. Before the changes Player2 responded to wasd, and the code worked properly. Now Player2 is unresponsive. Player1 has always responded.
Two different objects (Player1 and Player2) share the following script." Bubba73 You talkin' to me? 03:51, 22 April 2017 (UTC)[reply]


They don't exactly share a script. They each have their own instance of it. I'm not sure she understands that.
In general there's a lot of confusion here trying to use local variables as globals. Typically you'll want to create a singleton "game manager" or "game controller" that has score and stuff, and then the player code can interact with that.
Here's a simple example from one of the official Unity video tutorials. A "game controller" script is attached to an empty object in the scene. (Notice how the DestroyByObject script in that example does a FindByTag call, then it has a reference to the game controller and can then access its public members.)
https://unity3d.com/learn/tutorials/projects/space-shooter-tutorial/counting-points-and-displaying-score
All that said, I can't identify the specific bug that would cause the exact problem described. Hope something I said helps with her assignment. ApLundell (talk) 04:03, 22 April 2017 (UTC)[reply]

Oh. I think I have an idea. pOS and pTS are references, but there's no check if they're null. These are variables you've indicated are newly added. Because of the way she's got her scripts set up, she would have to manually set these variables in the editor twice. If she didn't set both of them for each player, it would hit a Null Reference Exception , and bail out of the FixedUpdate function for that player. I'll bet that's it. ApLundell (talk) 04:12, 22 April 2017 (UTC)[reply]

Thanks - I sent her a link to all of this but she went to bed about 2 hours ago. She'll see it tomorrow. Bubba73 You talkin' to me? 04:26, 22 April 2017 (UTC)[reply]
Hello Bubba73's daughter! I hope something in my above rambling is helpful! ApLundell (talk) 04:33, 22 April 2017 (UTC)[reply]
Resolved

She has player 2 working now. She thinks it was because the text displaying the scores was in FixedUpdate() instead of Update(). Bubba73 You talkin' to me? 15:41, 22 April 2017 (UTC)[reply]

That's good... But I hope she's also sorted out how she's doing the scoring. In object oriented programming, two instances of an object don't share member variables.They each have their own. ApLundell (talk) 17:34, 22 April 2017 (UTC)[reply]
  • Bubba73, this is just a quick infodump, but you can use <syntaxhighlight lang="c#"></syntaxhighlight> to produce better looking code in posts like these. I had actually changed it last night and was going to make a note, but I hit an edit conflict and then had to deal with my kids, and then forgot all about it (I just went ahead for the hell of it and so you can see what it looks like with this edit). I'm glad to see the problem got resolved. ᛗᛁᛟᛚᚾᛁᚱPants Tell me all about it. 17:40, 22 April 2017 (UTC)[reply]
    • Programmers have gotten so soft. Back in my day, we punched Fortran on cards. No syntax highlighting - everything was upper case. No indentation or blank lines either. And rarely a blank space that wasn't required.  :-) Bubba73 You talkin' to me? 21:00, 22 April 2017 (UTC)[reply]
[1] (be sure to turn annotations on). ᛗᛁᛟᛚᚾᛁᚱPants Tell me all about it. 23:31, 22 April 2017 (UTC)[reply]

Public key signatures[edit]

I have recently been introduced to public key cryptography. I came across this problem and I'm not sure how to approach it. If I send someone an encrypted message signed with my signature key, what's to prevent them from encrypting it again and sending it to other people pretending the message is directly from me?

Perhaps I haven't gotten my head around how public key signatures work. If my friend sends me a message signed by him, and I forward it to other people, they will think it's from him right? I'm assuming there is something I'm missing to prevent this situation.--Testing questions (talk) 15:05, 22 April 2017 (UTC)[reply]

If A writes a letter to B which begins "Dear B" and signs it with his (A's) private key, then B can't send it to C and convince C that A sent it directly to C, because of the salutation. Similarly, if it's an email message, it will have a To field in the header which identifies whom A sent it to. Of course B can't change the salutation or To header without invalidating the signature. On the other hand, if it's not a message but some other type of document which isn't specifically addressed to B, then B can indeed forward it to C via some unauthenticated channel and convince him that it came directly from A. It's up to C to recognize that the channel is insecure even though the message is signed. But in most cases this would be of limited value to B since A did indeed write the document, and the only thing B is spoofing is whom A sent it to. CodeTalker (talk) 15:42, 22 April 2017 (UTC)[reply]
So should you always try to directly address the recipient? What about certificates? Can they prevent recipients encrypting the message again and sending it to someone else?--Testing questions (talk) 15:50, 22 April 2017 (UTC)[reply]
The signature should verify that the exact text of the message was encrypted by the original author. You couldn't alter it and preserve that signature.
You could copy/paste the text into a new email, and add your own signature, taking credit for the other person's work. Or you could send the whole thing, signature and all, to a third party, but you couldn't alter it and then reapply the original person's signature. ApLundell (talk) 17:40, 22 April 2017 (UTC)[reply]
There's, of course, an article at Digital signature that is pretty good. ApLundell (talk) 17:43, 22 April 2017 (UTC)[reply]
The case where you "send the whole thing, signature and all, to a third party" is what I am interested in. That third party would believe it was sent directly to them from the signer with no intermediary. The signer may not have wanted them to see it. CodeTalker helpfully mentioned including salutations that the third party would notice. However, are there any technical means to prevent this happening? Is the only solution for the third parties be expected to do proper authentication so they know who the actual sender is? Is the anything the original signer do to prevent this situation?--Testing questions (talk) 19:02, 22 April 2017 (UTC)[reply]
Public key cryptography, by itself, has no concept of sending, receiving, or anything like that. All you get is blocks of data that are encrypted and/or signed. Public key crypto doesn't say anything about how those blocks are moved around, only where they come from and what can be done to them. If you wanted a cryptosystem that did verify *who* transmitted data, and what means it took to get to someone, you would have to build a more sophisticated system which included that information, and protected it appropriately with the relevant checks. In this case, as in most other applications of cryptography for data security, the actual crypto is the easy bit - building a worthwhile, workable system that solves real-world problems (using those basic cryptographic building blocks) is difficult, and quite apt leaving weaknesses which arise not from the crypto itself, but from the difficulties of using it safely. -- Finlay McWalter··–·Talk 19:46, 22 April 2017 (UTC)[reply]
Correct, what you're asking about is essentially an authenticated email system. Public key cryptography might be a component of such a system (as it is for DKIM for instance), but PKC by itself doesn't address such issues as authenticating the sender of a message, preventing spoofed resends, etc. CodeTalker (talk) 19:18, 23 April 2017 (UTC)[reply]
  • This is a real risk (it has been used to steal real money, in 10k+ amounts). Crypto is still so unfamiliar that almost all end-users have no real appreciation for what's happening or what they've received. This makes them prone to being deceived. A simple attack is to take something that is provably (and genuinely) from a trusted source, add some fraud, then wrap it up further with a technically valid signature from the overall fraudster. Every part of this is cryptographically valid (and so the tools don't highlight it as suspicious). The deception is to mislead the recipient as to who is vouching for what parts of it. Yet again, we're back to simple social engineering, which most software still doesn't watch out for.
As a learning tool, I'd suggest the command line version of OpenPGP and working with it to do a large number of tasks (many web guides) to become familiar with it long before you need to use such tools in any real-world situation. Then follow Bruce Schneier's blog. Andy Dingley (talk) 12:12, 24 April 2017 (UTC)[reply]
That's an interesting suggesting I will check out, thank you.--Testing questions (talk) 15:28, 25 April 2017 (UTC)[reply]